Java中匿名类的方法

Java中匿名类的方法,java,polymorphism,anonymous-class,Java,Polymorphism,Anonymous Class,有没有办法捕获匿名类的类型 // 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

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

// 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(); 
}            
}
在下面的示例中,如何调用匿名类的方法
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(); 
}            
}
注:saw&以及一些其他相关讨论

蒂亚

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

编辑:

下面的方法奏效了——无论它值多少钱,都离它更近了一步。在新对象上调用方法时不查找其引用类型

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

不,您不能呼叫g2。实际上,java中的匿名类是实现仅在一个地方使用的接口实例的一种简捷方法。对于指定的接口,要调用的方法应该由该接口具体定义

允许您定义非接口方法的原因是,当您想要实现helper方法时,设计者考虑了这种情况


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

您只能直接调用它,例如

new HelloWorld() {
    // ...
}.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(); 
}            
}
不可以。您只能访问它进行反射

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

// 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(); 
}            
}
由于它们只能从匿名类型本身内部引用,因此它们在匿名类型之外没有任何用处。所以,正如你所说,它们可以用来组织类内的逻辑,但仅此而已。唯一的例外是@bcsb1001描述的边缘情况,在这种情况下,您可以直接在匿名对象创建表达式(而不是分配给它的变量)上调用该方法

下面的工作

这是因为表达式
newhelloworld(){…}
的类型是匿名类的类型。由于创建表达式具有实际的匿名类类型,因此可以使用它访问它声明的任何成员。但是,由于该类是匿名的,因此它没有名称,因此不能声明具体匿名类型的变量。最接近的方法是声明变量
HelloWorld
。由于变量声明为
HelloWorld
,因此只能使用它访问在
HelloWorld
上声明的成员或其超类型之一


如果Java在声明中添加了对推断类型的支持,您可以编写类似于
var g=new HelloWorld(){…}
(C#style)或
autog=newhelloworld(){…}(C++风格),并且将从赋值中推断
g
的类型。这将允许您捕获匿名类型,而不需要类型名。但是,Java目前还没有这样的功能。

据我所知,这是不可能做到的,但您为什么还要这样做呢?为什么不用可调用的方法创建一个真正的类呢?@HovercraftFullOfEels阅读了第二部分——关于“为什么”的“疑惑”的短语。你在Java文档中遇到过对此的确凿证据吗?@user3880721你想要一个javadoc做什么?你想要这个@用户3880721“确认”什么?你不能对一个类型之外的、没有被该类型公开的类型调用方法吗
g2
是一个
HelloWorld
。值得注意的是,匿名类不需要声明为接口实现。它们可以被声明为任何非原语类型,一直到
Object
。是的,我认为这是最接近的。与getClass()相比,无法捕获Anonyman.class的类型以供进一步使用。