【问题标题】:Methods of anonymous classes in JavaJava中匿名类的方法
【发布时间】:2014-08-23 03:48:59
【问题描述】:

有没有办法捕获匿名类的类型?

在下面的例子中,我如何调用匿名类的方法g2?想不出一个绝对有用的具体案例。而且我知道匿名类是供“即时”使用的。然而,想知道。

如果我不能调用它,那么在匿名类中定义它(如果有的话——除了作为匿名类本身的其他方法的帮助者)有什么用?

// http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html

public class SomeClass {

    abstract class HelloWorld {  abstract public void greet();  }

    public void sayHello() {        
        class EnglishGreeting extends HelloWorld {  //  local class 
            String name = "world";
            public void greet() {  System.out.println("Heya " );    }
            public void gg() { System.out.println("do this as well.. ");}  }  
        HelloWorld englishGreeting = new EnglishGreeting();

        HelloWorld frenchGreeting = new HelloWorld() {  //  anonymous class 
            public void g2() { System.out.println("do this too.. ");}
            public void greet() {  System.out.println("Salute ");  }
        };  


        englishGreeting.greet();
        ((EnglishGreeting)englishGreeting).gg();
        frenchGreeting.greet();
//        ((frenchGreeting.getClass())frenchGreeting).g2();  // gives a checked error
    }  

    public static void main(String... args) {
        SomeClass myApp = new SomeClass();
        myApp.sayHello(); 
}            
}

注意:看到 Can't call anonymous class methodAnonymous Inner Classes Inside Methods 以及其他一些相关讨论。

TIA。

//=============================================== =

编辑:

下面的工作——不管它的价值如何,离它更近了一步。在新对象上调用该方法时不查找其引用类型。

        HelloWorld frenchGreeting = new HelloWorld() {
            public HelloWorld g2() { System.out.println("do this too.. ");  return this; }
            public void greet() {  System.out.println("Salute ");  }
        }.g2();  

【问题讨论】:

  • 据我所知这是不可能的,但你为什么还要这样做呢?为什么不创建一个带有可调用方法的真实类?
  • @HovercraftFullOfEels 阅读第二部分——关于“为什么”的“想知道”的短语。

标签: java polymorphism anonymous-class


【解决方案1】:

只能直接调用,例如

new HelloWorld() {
    // ...
}.g2();

但是,请注意,您不能分配变量并直接调用它,也不能在方法的其他地方调用它。不过,这是我能想到的最接近回答您问题的方法。

【讨论】:

  • 是的 - 我认为这是最接近的。无法捕获 anonym.class 的类型以供比 getClass() 进一步使用。
【解决方案2】:

不,您不能调用 g2。实际上,Java 中的匿名类充当了实现仅在一个地方使用的接口实例的捷径。指定接口,你要调用的方法应该由该接口具体定义。

之所以允许你定义非接口方法,是因为设计者在你想要实现辅助方法时考虑到了这种情况。

我认为匿名接口被广泛使用。

【讨论】:

  • 您在 Java 文档中是否遇到过对此的坚定验证?
  • @user3880721 你想要一个 javadoc 做什么?你要这个? docs.oracle.com/javase/tutorial/java/javaOO/…
  • @user3880721 对什么进行“严格验证”?您不能在该类型之外调用该类型未公开的类型上的方法? g2HelloWorld
  • 值得注意的是,匿名类不需要声明为 interface 实现。它们可以声明为任何非原始类型,一直到Object
【解决方案3】:

有没有办法捕获匿名类的类型?

没有。您只能访问它以进行反思。

如果我不能调用它,那么在匿名类中定义它(如果有的话——除了作为匿名类本身的其他方法的帮助者)有什么用?

因为它们只能在匿名类型本身中被引用,所以它们在它之外毫无用处。所以,正如你所说,它们可能被用来组织类中的逻辑,但仅此而已。唯一的例外是@bcsb1001 描述的边缘情况,在这种情况下,您直接在匿名对象创建表达式(而不是分配给它的变量)上调用该方法。

下面的工作...

这是因为表达式new HelloWorld() { ... } 的类型是匿名类的类型。由于创建表达式具有实际的匿名类类型,因此您可以使用它来访问它声明的任何成员。然而,由于类是anonymous,它没有名字,所以你不能声明一个具体匿名类型的变量。最接近的方法是声明变量HelloWorld。由于该变量被声明为HelloWorld,因此您只能使用它来访问在HelloWorld 或其超类型之一上声明的成员。

如果 Java 在声明中添加了对推断类型的支持,您可以编写类似 var g = new HelloWorld() { ... };(C# 风格)或 auto g = new HelloWorld() { ... };(C++ 风格)的内容,并且 g 的类型将从赋值中推断出来。这将允许您在不需要类型名称的情况下捕获匿名类型。但是,Java 目前还没有这样的能力。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-21
    • 1970-01-01
    相关资源
    最近更新 更多