我有一个用T参数化的泛型类.它包含T类型的数据,并且有一些使用类型T的方法.但是,如果T恰好是List< E>,我希望能够编写一个方法,我可以使用这个E作为一种类型,但我不确定是否有办法做到这一点.
举个例子,考虑一下:
class Test {
private T data;
public void setData(T t) {data = t;}
public T getData() { return data; }
}
现在假设这被实例化为Test< List< String>>.所以我们有一个带有getData方法的对象返回List< String>.在这个对象上,我想有一个像setCallback这样的方法,比如Callback< String>.换句话说,我需要一种方法,将用E参数化的接口作为其参数,其中E与T相关,如在列表< E>中. == T.
我该怎么写这个方法?
请注意,我不想强迫T成为List,例如将T声明为List< E>在类级别上,必须可以使用类Test< Integer>和测试< List< String>>,但仅在后一种情况下,setCallback方法才有意义.
我最接近的是:
interface AbstractCallback {}
interface Callback extends AbstractCallback> {
void onSomethingHappened(E e);
}
class Test {
...
void setCallback(AbstractCallback callback);
}
在这方面,我能做到
Test> test = new Test<>();
test.setCallback(new Callback() {
public void onSomethingHappened(String e) {}
});
这是有效的,如果T不是List,我将无法根据需要创建适合的Callback(因为除非T是List,否则根本无法创建实现AbstractCallback< T>的Callback实例).然而,被迫使用setCallback方法采用抽象超类(实际上是接口)而不是更具体的方法使得界面不清楚并且有点模糊.
我还考虑将setCallback放在Test的子类上,使得类SubTest< E>扩展测试< List< E>>但这意味着我必须实例化此类而不是Test,即使我将Test对象的构造委托给工厂,在构造时T的类型也是未知的(除非我添加Class参数来携带类型信息,我’d而不是) – 只有在调用了setData之后才能知道它.此外,我更喜欢如果客户只需要参考测试而不打算使用压缩等.
最后,我考虑过让客户端负责提供正确的类型,只需将E定义为与T无关的未绑定泛型类型,并简单地让不正确的调用导致ClassCastExceptions:
void setCallback(Callback callback);
有没有更好的方法呢?为了重新限制,基本上我想要声明一个泛型方法,该泛型方法具有与类’泛型类型T相关的泛型类型E,因此T等效于List< E> ;;理想情况下,如果T根本不是List,则无法调用该方法.所以你可以说这与一个E类相反,并用List< E>声明一个方法.甚至< T extends List< E>>.
我想这可能是不可能的,因为在编译时没有办法判断T是否是List,但也许有一个比我上面的建议更聪明的方法呢?
最佳答案 我不确定你是否想强迫T成为一个List.如果这样做,您可以使用两个泛型类型参数 – 一个用于元素,另一个用于List:
class Test> {
private T data;
public void setData(T t) {data = t;}
public T getData() { return data; }
}
现在,您可以在Test中编写使用E的方法.例如:
public E getFirst ()
{
if (data != null && data.size() > 0)
return data.get(0);
else
return null;
}
或者你可以消除T并只使用E:
class Test {
private List data;
public void setData(List t) {data = t;}
public List getData() { return data; }
}