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();}
then
HasA object=new HasA(){public void a(){…}@AndrewTobilko是的,但是实现不是内联的。我认为他们将其内联是有原因的。当然,不同的用法有不同的选项。“访问类的私有成员”私有成员是什么?