java - 在实例化类时声明函数

标签 java anonymous-inner-class

我遇到了以下 java 代码,但我不确定它是什么意思。我们可以在实例化一个类之后在'{'中编写代码吗,例如new TestClass { */code goes here */}

但是当我尝试运行代码时,我没有在输出中看到“Z is 10”。谁能给我一些链接,我可以从中获得与 Java 的此功能相关的更多信息。

class TestClass {
    int z;
    public TestClass(){
    z=10;
    }
    public int getZ(){
    return z;
    }
    public void setZ(int z){
    this.z=z;
    }
}

class A
{   
    public static void main (String[] args) throws java.lang.Exception
    {
    TestClass TC = new TestClass() {
            public void testprint() {
        System.out.println("Z is " + getZ());
        }
     };
    }
}

最佳答案

这是一个匿名内部类。它创建一个对象,该对象是某个类的实例,该类是 TestClass 的子类,您不想在其中为该子类命名(因为您只需要即时创建对象,而无需在任何地方使用该类否则)。

代码仅初始化对象,您实际上并未调用所创建对象的方法,因此您看不到任何输出。您可以在代码中添加一行

public static void main (String[] args) throws java.lang.Exception
{
    TestClass TC = new TestClass() {
        public void testprint() {
            System.out.println("Z is " + getZ());
        }
    };
    // <- call the new method (>_< this won't compile)
    TC.testprint(); 
}

除非这不起作用,因为 testprint 未定义为 TestClass 上的方法,引用对象的局部变量具有 TestClass 类型,因此编译器期望找到在 TestClass 或 TestClass 的父类(super class)上定义的方法。您可以向 TestClass 添加某种方法,如下所示:

abstract class TestClass {
    int z;
    public TestClass(){
        z=10;
    }
    public int getZ(){
        return z;
    }
    public void setZ(int z){
        this.z=z;
    }
    // add new method
    public abstract void testprint();
}

现在编译器知道期望 TestClass 类型的对象有一个名为 testprint 的方法。我不必使 TestClass 抽象,我可以向它添加测试打印的实现。但是,因为 TestClass 是抽象的,所以很明显新对象不是 TestClass 而是它的某个子类。

或者,通过另一个已经公开的 TestClass 方法调用此方法。使用您的 TestClass 不变,但将主要方法更改为:

public static void main (String[] args) throws java.lang.Exception
{
    TestClass TC = new TestClass() {
        public void testprint() {
            System.out.println("Z is " + super.getZ());
        }
        // override Z getter to call testprint
        @Override public int getZ(){ 
            testprint();
            return z;
        }
    };
    TC.getZ(); // <- call method on object created above
}

testprint 必须更改为调用 Z 的 getter 的父类(super class)版本,因此我们不会有无限递归。现在匿名子类上的 Z getter 调用了 testprint 方法,所以你可以调用 getter 并查看输出:

Z is 10

代码没有为子类分配一个名称,但它仍然分配了一个名称。如果我在 main 的末尾添加一行以查看内部调用的匿名类:

    System.out.println(TC.getClass());

它打印

class A$1

在实践中,不能直接调用匿名类中定义的新方法并不是限制。如果您想将一个类的实现传递给某个其他对象的方法,则您提供了一个匿名类,采用匿名类对象的东西不会知道(也不应该知道,请参阅 LSP ) 如何调用新方法。

关于java - 在实例化类时声明函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23294569/

相关文章:

java - java中匿名内部类成员不可访问

java indexOf 在应该返回正数时返回 -1

java - 在 jar 之间发送数据?

Java ProcessBuilder 和 Windows 系统变量

java - 在 JavaFX 应用程序线程上执行 TimerTasks 是否有比嵌套匿名 Runnable 更优雅的方法?

java - Java : new Stream<Integer>(){ . .. } 中的语法是什么意思?

java - Flink反序列化Kafka JSON

java - TestNG 无法通过线程测试失败

java - 如何将非最终变量传递给匿名内部类?

java - 如何从匿名内部类调用外部类父级中的成员变量