超级匿名班(Java)

时间:2018-08-21 19:56:01

标签: java anonymous-class

假设我们有代码:

public class Solution {
private String name;
private String surname;

Solution(String name, String surname) {
    this.name = name;
    this.surname = surname;
}
private String getPrivate() { return name; }
public String getPublic() { return surname; }

private void sout() {
    new Solution("Anonim private", "Anonim public") {
        void printName() {
            System.out.println(getPrivate());               // Main   private
          //System.out.println(this.getPrivate());          // can't compile
            System.out.println(super.getPrivate());         // Anonym private
            System.out.println(Solution.this.getPrivate()); // Main   private

            System.out.println("\n");

            System.out.println(getPublic());                // Anonym public
            System.out.println(this.getPublic());           // Anonym public
            System.out.println(super.getPublic());          // Anonym public
            System.out.println(Solution.this.getPublic());  // Main   public

        }
    }.printName();
}
public static void main(String[] args) {
    new Solution("Main   private", "Main   public").sout();
}}

评论-我们的输出(通过intellij的想法)

问题:为什么super.getPrivate()返回字符串"Anonym private"

如果我们查看Java文档,将会看到

  

如果您的方法覆盖其超类的方法之一,则可以通过使用关键字super来调用覆盖的方法。

但是在这种情况下,获得了super一词的另一个含义:内部类的实例。您可以添加以下内容进行检查:

System.out.println(super.getClass());
System.out.println(this.getClass());

2 个答案:

答案 0 :(得分:1)

  

问题:为什么super.getPrivate()返回字符串"Anonym private"

     

如果我们查看Java文档,将会看到

     
    

如果您的方法覆盖其超类的方法之一,则可以通过使用关键字super来调用覆盖的方法。

  
     

但是在这种情况下,获得了super单词的另一个含义:instance   内部类。

不。您引用的super的含义在此适用。上下文是这样的:

private class Solution {
     

[...]

private void sout() {
    new Solution("Anonim private", "Anonim public") {
            void printName() {
     

[...]

                System.out.println(super.getPrivate());

您已经意识到上下文是内部类的方法,因此第一个要回答的问题是super所指的是内部类的超类?但这很容易:它的超类是Solution,这就是“ new Solution(...)”部分表示的意思。

下一个要问的问题是该实例的属性是什么?这也很容易:这是通过与提供的参数匹配的构造函数对其进行初始化的结果。因此,完全自然并且期望super.getPrivate()会先读取其中的一个。

由于内部类不会覆盖getPrivate(),因此不需要使用super -在内部类实例本身上调用getPrivate()都会获得相同的结果,无论内部对象是在内部。内部类实现或外部实现。

与内部类的包含类的包含实例无关。包含类也是 Solution的意思是使您感到困惑和挑战。包含实例是与内部类实例不同的对象。与内部类实例名称相同的方法和变量(即所有方法和变量)从内部类实例中隐藏,只能通过Solution.this构造访问。

答案 1 :(得分:0)

如果在终端上使用javac Solution.java编译代码,则有两个文件,它们的名称分别是Solution.classSolution$1.class,它们是(本地)内部类。

Solution.class

public class Solution {
  private String name;
  private String surname;

  Solution(String paramString1, String paramString2) {
    name = paramString1;
    surname = paramString2; }

  private String getPrivate() { return name; }
  public String getPublic() { return surname; }


  private void sout()
  {
    new Solution.1(this, "Anonim private", "Anonim public").printName();
  }

  public static void main(String[] paramArrayOfString) { 
       new Solution("Main   private", "Main   public").sout(); 
  }
}

解决方案$ 1.class

import java.io.PrintStream;

class Solution$1
  extends Solution
{
  Solution$1(Solution paramSolution, String paramString1, String paramString2) { 
           super(paramString1, paramString2); 
  }

  void printName() { 

    System.out.println(Solution.access$000(this$0));    // Main   private        
    System.out.println(Solution.access$000(this));      // Anonym private
    System.out.println(Solution.access$000(this$0));    // Main   private

    System.out.println("\n");

    System.out.println(getPublic());           // Anonym public
    System.out.println(getPublic());           // Anonym public
    System.out.println(super.getPublic());     // Anonym public
    System.out.println(this$0.getPublic());    // Main public
  }
}

如您所见,this$0代表封闭的类对象,this代表(本地)内部类对象。

  

问题:为什么super.getPrivate()返回字符串"Anonym private"

从反编译的角度来看,Java选择那样工作;)