21

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

Date date = new Date() {
    public void someMethod() {}
}

我想知道是否可以从外部调用此方法,类似于:

date.someMethod();
4

6 回答 6

31

好问题。答案是否定的。你不能直接打电话date.someMethod();
让我们先了解一下这是什么。

Date date = new Date()  { ... }; 

上面是匿名(没有名字)子类,它扩展了 Date 类。

当你看到这样的代码时,

    Runnable r = new Runnable() {

        public void run() {

        }

    };

这意味着您已经定义了匿名(没有名称)类,该类正在实现(未扩展)可运行接口。

因此,当您调用date.someMethod()它时,它将无法调用,因为someMethod未在上述情况下定义超类是类。它遵循简单的覆盖规则。superclass.Date

但是,如果你想打电话,someMethod那么接下来就是步骤。

第一种方式>
带引用变量 ' date'
date.getClass().getMethod("someMethod").invoke(date);

第二种方式>
使用新创建的 Date 类对象的匿名子类。

new Date() 
{
    public void someMethod() {
          System.out.println("Hello");
    }
}.someMethod();   //this should be without reference 'date'
于 2013-03-20T16:22:11.347 回答
9

基本上没有。

然而,这种丑陋可以做到......

Date date = new Date() {
  public Date someMethod() { 
     //do some stuff here
     return this;
  }
}.someMethod();

但除此之外,您只能使用反射调用该方法(父类中不存在),如下所示:

date.getClass().getMethod("someMethod").invoke(date);

(为了清楚起见,try-catch 被忽略了......)

但说真的,不要这样做!如果我在必须处理的代码库中偶然发现此代码,我会感到被编写此代码的人讨厌。

于 2013-03-20T15:20:14.060 回答
8

如果不使用反射,则不能:该方法不是 Date API 的一部分,date就编译器而言只是一个日期。

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

new Date() { public void someMethod() { } }.someMethod();
于 2013-03-20T15:19:51.067 回答
6

在 Java 10+ 中,使用var关键字

var date = new Date() {
    public void someMethod() { }
};

date.someMethod();
于 2019-07-11T02:20:24.157 回答
2

不,这就是方法本地类的用途。

 class MyDate extends Date() {
   public void someMethod() {...}
 }
 MyDate date = new MyDate();
 date.someMethod();
于 2013-03-20T15:21:32.233 回答
1

我不知道你为什么要这样做,但正如所写的那样,这是不可能的,因为Date没有声明someMethod.

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

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

  MyDate date = new MyDate( );

  date.someMethod( );
}

再一次,我建议normal首先使用一个类,因为本地类,就其性质而言,不能被测试。

于 2013-03-20T15:20:59.020 回答