匿名类作为泛型参数

时间:2015-11-20 11:25:47

标签: java generics lambda anonymous-class


我想创建一个类,从匿名类定义中获取一个对象来存储。我使用泛型类来实现它。然后我想使用功能接口定义一些操作,这些接口将此对象作为参数来使用 代码说的不仅仅是文字。所以看看这个:

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
        });
    }
}

我的问题是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();
    }
}

这非常完美,可以打印出来&#34; Something&#34;。但是我的第一种方法有什么问题?我真的没有在这里得到问题。

2 个答案:

答案 0 :(得分:2)

问题是你的匿名类仍然必须符合(扩展或实现)某种类型,而你选择的类型是Object,它没有你的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);
        });
    }
}

答案 1 :(得分:1)

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

此处的编译器正在用您的匿名类替换T中的Test,因为该类包含变量text,这就是第二种情况的原因。