这是一个匿名内部类。它创建了一个对象,该对象是某个类的子类 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 的超类上定义的方法。您可以向 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 抽象,我可以向它添加一个 testprint 的实现。但是,因为 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 的超类版本,因此我们不会有无限递归。现在匿名子类上的 Z getter 调用 testprint 方法,因此您可以调用 getter 并查看输出:
Z is 10
该代码没有为子类分配名称,但仍会为其分配一个名称。如果我在 main 的末尾添加一行以查看内部调用的匿名类:
System.out.println(TC.getClass());
它打印
class A$1
实际上,不能直接调用在匿名类中定义的新方法并不是限制。如果您想将类的实现传递给其他对象的方法,则提供匿名类,获取匿名类对象的东西不知道(也不应该知道,请参阅LSP)如何无论如何都要调用新方法。