[英]Can I access new methods in anonymous inner class with some syntax?
是否有Java語法可以訪問外部類中匿名內部類中定義的新方法? 我知道可以有多種解決方法,但我想知道是否存在特殊語法?
例如
class Outer {
ActionListener listener = new ActionListener() {
@Override
void actionPerformed(ActionEvent e) {
// do something
}
// method is public so can be accessible
public void MyGloriousMethod() {
// viva!
}
};
public void Caller() {
listener.MyGloriousMethod(); // does not work!
}
}
我自己的解決方案
我只是將所有方法和成員移至外部類。
一旦匿名類實例被隱式轉換為命名類型,便無法回退,因為匿名類型沒有名稱。 用戶可以通過訪問匿名內部類的附加構件this
類中,在表達后立即表達和類型可以推斷,並通過一個方法調用返回。
Object obj = new Object() {
void fn() {
System.err.println("fn");
}
@Override public String toString() {
fn();
return "";
}
};
obj.toString();
new Object() {
void fn() {
System.err.println("fn");
}
}.fn();
identity(new Object() {
void fn() {
System.err.println("fn");
}
}).fn();
...
private static <T> T identity(T value) {
return value;
}
我班上的一位學生問我們的教授是否有一天可以做到這一點。 這是我寫的一個很酷的概念證明,盡管不值得,但實際上是可以做到的,這是可以做到的,這是如何做到的:
public static void main(String[] args){
//anonymous inner class with method defined inside which
//does not override anything
Object o = new Object()
{
public int test = 5;
public void sayHello()
{
System.out.println("Hello World");
}
};
//o.sayHello();//Does not work
try
{
Method m = o.getClass().getMethod("sayHello");
Field f = o.getClass().getField("test");
System.out.println(f.getInt(o));
m.invoke(o);
} catch (Exception e)
{
e.printStackTrace();
}
}
通過使用Java的Method類,我們可以通過傳入方法的字符串值和參數來調用方法。 字段可以完成相同的操作。
只是認為分享這很酷!
您的調用者將listener
稱為ActionListener
,因此對該新方法一無所知。 我認為,做到這一點的唯一方法(除了進行反射體操之外,這實際上會破壞使用匿名類(即,快捷方式/簡單性)的目的)只是對ActionListener
進行子類化而不使用匿名類。
不,這是不可能的。 您需要將ActionListener強制轉換為其真實的子類名稱,但是由於它是匿名的,因此沒有名稱。
正確的方法是使用反射:
import java.lang.reflect.InvocationTargetException;
public class MethodByReflectionTest {
public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
Object obj = new Object(){
public void print(){
System.out.println("Print executed.");
}
};
obj.getClass().getMethod("print", null).invoke(obj, null);
}
}
您可以在此處檢查: 以字符串形式給出方法名稱時,如何調用Java方法?
有趣的是,現在可以使用var
結構(Java 10或更高版本)來實現。 例:
var calculator = new Object() {
BigDecimal intermediateSum = BigDecimal.ZERO;
void calculate(Item item) {
intermediateSum = Numbers.add(intermediateSum, item.value);
item.sum= intermediateSum;
}
};
items.forEach(calculator::calculate);
這里帶有方法參考,但是當然也適用於點方法調用。 它也適用於字段。 享受新的Java。 :-)
我在這里找到了有關var
和匿名類的更多技巧: https : //blog.codefx.org/java/tricks-var-anonymous-classes/
是的,如果您有任何疑問,請訪問下面的示例,請發表評論
package com;
interface A
{
public void display();
}
public class Outer {
public static void main(String []args)
{
A a=new A() {
@Override
public void display() {
System.out.println("Hello");
}
};
a.display();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.