Java 匿名类作为泛型参数

Java 匿名类作为泛型参数,java,generics,lambda,anonymous-class,Java,Generics,Lambda,Anonymous Class,我想创建一个类,该类从匿名类定义中获取一个要存储的对象。我使用了一个泛型类型类来实现这一点。然后,我想使用函数接口定义一些操作,这些函数接口将此对象作为要处理的参数。 代码比文字更能说明问题。看看这个: public class Test<T> { @FunctionalInterface public interface operation<T> { void execute(T object); } private T


我想创建一个类,该类从匿名类定义中获取一个要存储的对象。我使用了一个泛型类型类来实现这一点。然后,我想使用函数接口定义一些操作,这些函数接口将此对象作为要处理的参数。
代码比文字更能说明问题。看看这个:

public class Test<T> {
    @FunctionalInterface
    public interface operation<T> {
        void execute(T object);
    }
    private T obj;
    public Test(T _obj){
        obj = _obj;
    }
    public void runOperation(operation<T> op){
        op.execute(obj);
    }

    public static void main(String[] args){
        Test<?> t = new Test<>(new Object(){
            public String text = "Something";
        });
        t.runOperation((o) -> {
            System.out.println(o.text);  // text cannot be resolved
        });
    }
}
公共类测试{
@功能接口
公共接口操作{
无效执行(T对象);
}
私人T obj;
公共测试(T_obj){
obj=_obj;
}
公共运营(运营op){
op.execute(obj);
}
公共静态void main(字符串[]args){
测试t=新测试(新对象(){
公共字符串text=“某物”;
});
t、 运行操作((o)->{
System.out.println(o.text);//无法解析文本
});
}
}
我的问题是无法解决函数接口实现中的o.text。这是某种类型的擦除结果吗?
有趣的是,当我在构造函数中实现函数接口时,我可以让这段代码正常工作。
请查看以下代码:

public class Test<T> {
    @FunctionalInterface
    public interface operation<T> {
        void execute(T object);
    }
    private T obj;
    private operation<T> op;

    public Test(T _obj, operation<T> _op){
        obj = _obj;
        op = _op;
    }
    public void runOperation(){
        op.execute(obj);
    }
    public static void main(String[] args){
        Test<?> t = new Test<>(new Object(){
            public String text = "Something";
        }, (o) -> {
            System.out.println(o.text);
        });
        t.runOperation();
    }
}
公共类测试{
@功能接口
公共接口操作{
无效执行(T对象);
}
私人T obj;
私人经营;
公共测试(T_obj,操作){
obj=_obj;
op=_op;
}
公共运行{
op.execute(obj);
}
公共静态void main(字符串[]args){
测试t=新测试(新对象(){
公共字符串text=“某物”;
},(o)->{
System.out.println(o.text);
});
t、 runOperation();
}
}
这很好用,可以打印出“某物”。但我的第一种方法有什么问题?我真的不明白这里的问题。

testt=newtest(newobject()){
  Test<?> t = new Test<>(new Object(){
            public String text = "Something";
        }, (o) -> {
            System.out.println(o.text);
        });
公共字符串text=“某物”; },(o)->{ System.out.println(o.text); });

这里的编译器将用匿名类替换
Test
中的
T
,因为该类包含变量
text
,这就是第二种情况有效的原因

问题在于匿名类仍然必须符合(扩展或实现)某种类型,而您选择的类型是
对象
,它没有
文本
属性。为了引用某种类型的属性,您需要使用实际的类或接口,因此编译器可以保证对象上有哪些可用的属性和方法

这很有效

public class Test<T> {

    public static class Data {
        public String text;
    }

    @FunctionalInterface
    public interface Operation<K> {
        void execute(K object);
    }

    private T obj;
    private Operation<T> op;

    public Test(T obj) {
        this.obj = obj;
    }

    public void runOperation(Operation<T> op) {
        op.execute(obj);
    }

    public static void main(String[] args) {
        Test<Data> t = new Test<>(new Data() {{
            this.text = "Something";
        }});

        t.runOperation((o) -> {
            System.out.println(o.text);
        });
    }
}
公共类测试{
公共静态类数据{
公共字符串文本;
}
@功能接口
公共接口操作{
无效执行(K对象);
}
私人T obj;
私人经营;
公共测试(T obj){
this.obj=obj;
}
公共运营(运营op){
op.execute(obj);
}
公共静态void main(字符串[]args){
测试t=新测试(新数据(){{
this.text=“某物”;
}});
t、 运行操作((o)->{
System.out.println(o.text);
});
}
}

在第二段代码中

    new Test<>(new Object(){
        public String text = "Something";
    }, (o) -> {
        System.out.println(o.text);
    });

不编译。这里,基于变量
t
的类型推断lambda的类型,即
Test
。因此,
runOperation
的参数必须是
operation
runOperation
的唯一有效参数是
null

Ok,但是为什么编译器不在第一种情况下用我的匿名类替换t呢?确实如此,但是匿名类的类型是
对象
,它没有名为
文本
的属性,因此您得到了编译错误。new Object(){公共字符串text=“Something”;})
    t.runOperation((o) -> {
        System.out.println(o.text);  // text cannot be resolved
    })