Java 创建对象时声明方法
为什么第一种方法是正确的,而第二种方法不是Java 创建对象时声明方法,java,object,methods,anonymous-class,anonymous-inner-class,Java,Object,Methods,Anonymous Class,Anonymous Inner Class,为什么第一种方法是正确的,而第二种方法不是 第一种方式: new Object() { public void a() { /*code*/ } }.a(); 第二种方式: Object object = new Object() { public void a() { /*code*/ } }; object.a(); 在哪里可以找到有关它的更多信息?在第二个选项中,您将新对象指定给类型为object的引用。因此,只能
第一种方式:
new Object() {
public void a() {
/*code*/
}
}.a();
第二种方式:
Object object = new Object() {
public void a() {
/*code*/
}
};
object.a();
在哪里可以找到有关它的更多信息?在第二个选项中,您将新对象指定给类型为
object
的引用。因此,只能对该引用调用java.lang.Object
中定义的方法
在第一个选项中,您基本上创建了扩展java.lang.object
的匿名类的新对象。该匿名类具有附加的方法a()
,这就是您可以调用它的原因。没有声明a
方法(2),而new Object(){public void a(){}
返回的匿名类有(1)
使用Java10(var
)使第二个选项与第一个选项一样有效
var object = new Object() {
public void a() {}
};
object.a();
Java是静态类型的。当您说
object.a()
时,它正在object
类中查找不存在的方法a
。因此它不编译
您可以使用反射获得对象
的方法,如下所示:
Object object = new Object() {
public void a() {
System.out.println("In a");
}
}
Method method = object.getClass().getDeclaredMethod("a");
method.invoke(object, null);
这会打印出来
在一个
别担心,你得做点修正 这两种方法都是访问类的私有成员的方法。通过使用第一种方法,您不必预先声明方法。例如:-
public class demo {
public static void main(String[] args) {
new Object() {
public void a() {
/*code*/
System.out.println("Hello");
}
}.a();
}
}
但是通过使用第二种方法,您必须显式声明方法a();无论是在抽象类中还是在接口中,都可以重写它。比如:-
interface Object
{
public void a();
}
class demo {
public static void main(String[] args) {
Object object = new Object() {
public void a() {
System.out.println("Hello");
}
}; object.a();
}
}
我希望这会有所帮助。那不是真的。Java使用静态类型(您可以在示例中看到它-
对象--您刚刚声明了它的类型!)。它使用多态性来确定应该调用哪个方法,但这与动态类型不同。关于动态与静态的一些争论你应该指出,通过反射调用方法是OP最不希望看到的:)@MatthewRock JVM确实支持动态分派,但是@SolomonUcko JVM不是Java。动态分派也不是使语言成为静态语言的东西。C++对虚拟方法有动态调度,但仍然是静态语言。注意,代码> var var >代码在java 10中引入,在较低版本中不可用。通过说Object Object=
你正在向下转换到一个Object
,var
给出了Object
的实际正确类型,定义了a()
。@SombreroChicken我理解var
的效果。但是除了问题中的第一个语法之外,没有其他方法(我知道)对匿名类型进行静态引用。现在我知道,var
可以用于此。更重要的是,它允许从匿名类进行多个方法调用。我发现这是一个新奇有趣的故事!您还可以声明一个具有a()
方法的接口,并从该接口创建一个匿名对象,而不是object
,后者将在不支持var
的较低版本中工作。例如,private interface HasA{public void a();}
thenHasA object=new HasA(){public void a(){…}代码>@AndrewTobilko是的,但是实现不是内联的。我认为他们将其内联是有原因的。当然,不同的用法有不同的选项。“访问类的私有成员”私有成员是什么?