我遇到了以下java代码,我不确定它是什么意思。我们可以在' {'在我们实例化一个类之后,例如新的TestClass {* / code goes here * /}
但是当我尝试运行代码时,我看不到Z是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());
}
};
}
}
答案 0 :(得分:8)
这是一个匿名的内部类。它创建了一个对象,它是一个子类的实例,它是子类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的impelmentation。但是,因为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
实际上,无法直接调用匿名类中定义的新方法不是限制。如果要将类的实现传递给某个其他对象的方法,则提供匿名类,获取匿名类对象的东西不会知道(并且不应该知道,请参阅{{3无论如何都要调用新方法。
答案 1 :(得分:2)
这是匿名内部类的例子。它就像一个扩展TestClass的类。因此,您不会调用该类的任何方法,因此不会打印
答案 2 :(得分:1)
执行此操作时,您将隐式子类化TestClass
并立即对其进行实例化,并添加方法testPrint()
。
这称为Anonymous Class。
答案 3 :(得分:1)
在您的代码中
TestClass TC = new TestClass() {
public void testprint() {
System.out.println("Z is " + getZ());
}
};
这称为Annonymous Inner Class所以这只会初始化。您可以在上面的代码段后使用TC.testprint();
。
注意 - TC没问题。但根据Java命名约定规则使用简单的字母。 您可以在此处阅读更多内容 - http://www.iwombat.com/standards/JavaStyleGuide.html
答案 4 :(得分:0)
这称为匿名类。它在幕后的作用是创建一个扩展给定类或实现给定接口的子类。您可以在此处阅读有关匿名类的更多信息: http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html