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