匿名 class 作为通用参数
anonymous class as generic parameter
我想创建一个 class 来从匿名 class 定义中获取对象进行存储。我使用通用类型 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();
}
}
这完美地打印出来 "Something"。但是我的第一种方法有什么问题?我真的不明白这里的问题。
Test<?> t = new Test<>(new Object(){
public String text = "Something";
}, (o) -> {
System.out.println(o.text);
});
此处的编译器正在用您的匿名 class 替换 Test
中的 T
,因为 class 包含一个变量 text
这就是第二种情况的原因作品。
问题是您的匿名 class 仍然必须符合(扩展或实现)某种类型,而您选择的类型 Object
没有您的 text
属性。为了引用某种属性,您需要一个实际的 class 或接口才能使用,因此编译器可以保证对象上可用的属性和方法。
这有效。
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);
});
}
}
第二段代码中,
new Test<>(new Object(){
public String text = "Something";
}, (o) -> {
System.out.println(o.text);
});
编译是因为构造函数调用的 Test
的类型参数被推断(因为使用了菱形运算符),并且它被推断为第一个参数计算结果的匿名类型(匿名 class 类型),因此第二个参数的类型是 operation<that anonymous class type>
,这是有效的。
在第一段代码中,表达式
t.runOperation((o) -> {
System.out.println(o.text); // text cannot be resolved
})
不编译。这里,lambda的类型是根据变量的类型t
推断出来的,即Test<?>
。因此,runOperation
的参数必须是 operation<some unknown type>
。 runOperation
的唯一参数是 null
.
我想创建一个 class 来从匿名 class 定义中获取对象进行存储。我使用通用类型 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();
}
}
这完美地打印出来 "Something"。但是我的第一种方法有什么问题?我真的不明白这里的问题。
Test<?> t = new Test<>(new Object(){
public String text = "Something";
}, (o) -> {
System.out.println(o.text);
});
此处的编译器正在用您的匿名 class 替换 Test
中的 T
,因为 class 包含一个变量 text
这就是第二种情况的原因作品。
问题是您的匿名 class 仍然必须符合(扩展或实现)某种类型,而您选择的类型 Object
没有您的 text
属性。为了引用某种属性,您需要一个实际的 class 或接口才能使用,因此编译器可以保证对象上可用的属性和方法。
这有效。
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);
});
}
}
第二段代码中,
new Test<>(new Object(){
public String text = "Something";
}, (o) -> {
System.out.println(o.text);
});
编译是因为构造函数调用的 Test
的类型参数被推断(因为使用了菱形运算符),并且它被推断为第一个参数计算结果的匿名类型(匿名 class 类型),因此第二个参数的类型是 operation<that anonymous class type>
,这是有效的。
在第一段代码中,表达式
t.runOperation((o) -> {
System.out.println(o.text); // text cannot be resolved
})
不编译。这里,lambda的类型是根据变量的类型t
推断出来的,即Test<?>
。因此,runOperation
的参数必须是 operation<some unknown type>
。 runOperation
的唯一参数是 null
.