Java 从匿名类调用新定义的方法

Java 从匿名类调用新定义的方法,java,anonymous-class,anonymous-methods,Java,Anonymous Class,Anonymous Methods,我实例化了一个匿名类的对象,并向其添加了一个新方法 Date date = new Date() { public void someMethod() {} } 我想知道是否可以从外部调用此方法,类似于: date.someMethod(); 如果不使用反射,则无法执行:该方法不是Date API的一部分,并且就编译器而言,Date只是一个日期 使用someMethod的唯一方法是直接在新创建的实例上调用它: new Date() { public void someMethod()

我实例化了一个匿名类的对象,并向其添加了一个新方法

Date date = new Date() {
    public void someMethod() {}
}
我想知道是否可以从外部调用此方法,类似于:

date.someMethod();

如果不使用反射,则无法执行:该方法不是Date API的一部分,并且就编译器而言,
Date
只是一个日期

使用
someMethod
的唯一方法是直接在新创建的实例上调用它:

new Date() { public void someMethod() { } }.someMethod();
基本上没有

然而,这种丑陋可以做到这一点

Date date = new Date() {
  public Date someMethod() { 
     //do some stuff here
     return this;
  }
}.someMethod();
但除此之外,您只能使用反射调用该方法(父类中不存在),如下所示:

date.getClass().getMethod("someMethod").invoke(date);
(为了清晰起见,请尝试省略捕捉…)


但是说真的,不要这样做如果我在我必须处理的代码库中偶然发现这一点,我会感到被编写此代码的人所憎恨。

我不知道你为什么要这样做,但在编写时这是不可能的,因为
Date
没有声明
someMethod

但是,您可以在方法内声明本地类,例如:

void foo ( )
{
  class MyDate extends Date
  {
     public void someMethod( );
  }

  MyDate date = new MyDate( );

  date.someMethod( );
}

再一次,我建议首先使用
普通
类,因为本地类本质上无法测试。

不,这就是本地类的方法

 class MyDate extends Date() {
   public void someMethod() {...}
 }
 MyDate date = new MyDate();
 date.someMethod();

好问题。答案是否定的。您不能直接调用
date.someMethod()
让我们先了解一下这是什么

Date date = new Date()  { ... }; 
上面是匿名(没有名字)子类,它正在扩展日期类。

当您看到这样的代码时,

    Runnable r = new Runnable() {

        public void run() {

        }

    };
这意味着您已定义了匿名(无名称)类,该类正在实现(不扩展)可运行接口。

因此,当您调用
date.someMethod()
时,它将无法调用,因为
someMethod
不是在
超类中定义的。它遵循简单的覆盖规则。

但如果仍要调用
someMethod
,请执行以下步骤。


第一种方式>
带有参考变量“
日期”

date.getClass().getMethod(“someMethod”).invoke(日期)

第二条道路>
使用Date类对象的新创建的匿名子类

new Date() 
{
    public void someMethod() {
          System.out.println("Hello");
    }
}.someMethod();   //this should be without reference 'date'

在Java10+中,使用
var
关键字

var-date=新日期(){
public void someMethod(){}
};
date.someMethod();

为什么不试试看它是否编译和运行?为什么要使用匿名类?你这样做的动机是什么?事实上,这是一种最好不要使用匿名类的情况。你可能可以用反射来实现,但你可能不想…最后一行没有编译。我想知道是否有可能以类似于最后一行的方式调用此方法。@HoverCraftFullOfels所以使用匿名类的最佳位置是当我分别重写或实现父类和接口的方法时?嗯,我不知道您可以在创建时调用非API方法。“我不知道这是为了什么?”我不知道,也许没有目的。只是匿名内部类表达式的类型是该内部类,而不是其命名的父类。因此,这更像是编译器不阻止您调用AIC的公共方法,即使它们在其他任何地方都无法访问。老实说,我从未使用过它,但从编译器的角度来看,它是有意义的。@assylias,这不是唯一的解决方案。反射也是可能的,正如Ppeterka和AmitG的回答所示。因此,我在我的问题中发布了一个类似的问题,即不管超类型(类或接口)是否声明了该方法,匿名类都应该能够定义自己的方法,如的Oracle Java SE教程中所述。请参考我在原始问题中共享的链接。