2013-03-20 28 views
12

我实例化了一个匿名类的对象,我添加了一个新方法。从匿名类调用新定义的方法

Date date = new Date() { 

     public void someMethod() { } 

    } 

我想知道是否有可能从外部某种程度上类似于调用这个方法:

date.someMethod(); 
+2

为什么你不试试看它是否编译并运行? – Claudiu 2013-03-20 15:17:17

+2

为什么要使用匿名类 - 这是什么动机?事实上,这是一个最好**不使用匿名类的情况。 – 2013-03-20 15:17:22

+1

你可以用反射来做,但你可能不想... – Lucas 2013-03-20 15:17:35

回答

22

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

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

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

当你看到这样的代码,

Runnable r = new Runnable() { 

     public void run() { 

     } 

    }; 

这意味着你已经定义匿名(没有名字)类,这是实现(不延长)Runnable接口。

所以,当你调用date.someMethod()不会能够调用因为someMethodsuperclass.规定在上述情况下超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' 
8

不使用反射不能:该方法不日期API和date的一部分只是编译器所关心的一个日期。

可以使用someMethod的唯一方法是通过调用它直接对新创建的实例:

new Date() { public void someMethod() { } }.someMethod(); 
+0

呵呵,我不知道你可以在创建时调用一个非API方法。我不知道这有什么用途? – iamnotmaynard 2013-03-20 15:28:28

+0

@iamnotmaynard可能没有目的。这只是一个匿名内部类表达式的类型是内部类,而不是它的命名父类。所以更多的情况是编译器不能阻止**你调用AIC的公共方法,即使他们永远无法在其他地方访问。 – millimoose 2013-03-20 16:08:31

+0

我从来没有用它来说实话,但从编译器的角度来看它是有意义的。 – assylias 2013-03-20 16:08:49

8

基本没有。

这uglyness可以做到这一点但...

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

但是不谈,你只能打电话只使用反射该方法(这并不在父类中存在的),这样:

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

(的try-catch为了清楚起见,省略了......)

但严重的是,不这样做!如果我在一个代码库中偶然发现了这个代码,我会感到被编写代码的人所恨。

1

我不知道你为什么要这样做,但正如所写,这是不可能的,因为Date不宣布someMethod

但是你可以声明在方法内部局部类,e.g:

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

    MyDate date = new MyDate(); 

    date.someMethod(); 
} 

再次,我会建议使用normal类第一,因为本地类,根据其性质,无法进行测试。

2

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

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

这个答案是错误的。 – Pacerier 2014-08-25 07:43:52