假设我有类似的类结构
public abstract class A
{
public String id;
}
public class B extends A
{
id = "b";
}
public class C extends A
{
id = "c";
}
public class test
{
ArrayList<A> as = new ArrayList<A>();
a.add(new B());
a.add(new C());
public *what goes here* get(String s)//returns a subtype of A, not A
{
for(A a : as)
{
if(a.id.equals(s))//or a.getClass().toString()
{
return a;//but need as subtype of A, not A
}
}
//throw some exception here when id is not found
}
}
如果我跑了
,我该怎么做呢?B b = get("b");
我不会在这里收到编译器警告?我不希望在我的代码中检查丑陋的instanceof,并且显式地转换为B也不是我想要的。我认为泛型可能是要走的路,但我对它们并不是很有经验。
我知道这不起作用,但这是我正在寻找的东西
public T extends A get(String s)
其中T扩展A是返回类型
答案 0 :(得分:2)
我能够用泛型做到这一点。
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
// Do something with the url here
}
我必须使用类参数而不是String。
这里方法主要打印:
public class B extends A {
public int n = 2;
public void doBThing()
{
System.out.println(n);
}
}
public class Runner
{
static ArrayList<A> as = new ArrayList<>();
public static void main(String[] args)
{
as.add(new B());
as.add(new C());
System.out.println(get(C.class).getClass().toString());
System.out.println(get(B.class).getClass().toString());
get(B.class).doBThing();
}
public static <T> T get(Class<T> toGet)
{
for(A a : as)
{
if(toGet.isInstance(a))
{
return toGet.cast(a);
}
}
return (T)(new A());
}
}
现在更频繁地使用这个技巧了!
get()没有返回类型B,但只要参数为B.class就被视为处理
答案 1 :(得分:0)
单个函数可能不会返回多个类型,必须在编译时知道。
所以你做不到
public (A or B) get(...) {}
如果不是类型擦除,你可以使用Java 5中引入的协变返回类型属性,它允许你这样做:
public C get(Class<C> t){
//check match against t
return istanceC;
}
public B get(Class<B> t){
//check match against t
return istanceB;
}
但是你会得到一个编译错误,说Class和Class有相同的擦除(因为它们都被上传到Class)。
编辑
基于kreinerjm的回答和this answer,实际上可以使用以下形式进行上述工作:
public <T extends A> T get(Class<T> type) {
//check and return
return (T) a;
}
这样,演员阵容更安全,因为你只能进入从A延伸的T。