我的课程如下。
public interface ITest <T>
{
public Set<T> methodHere();
}
public class test1 implements ITest<String>
{
Set<String> methodHere(){
return // Set of String
}
}
public class test2 implements ITest<Integer>
{
Set<Integer> methodHere(){
return // Set of Integer
}
}
public class ITestFactory {
public static ITest getInstance(int type) {
if(type == 1) return new test1();
else if(type == 2) return new test2();
}
}
public class TestUser {
public doSomething(int type) {
ITest t = ITestFactory.getInstance(type);
if(type == 1) Set<Integer> i = t.methodHere();
else if(type == 2) Set<String> s = t.methodHere();
...
}
}
工厂类中有一个警告,即ITest用作原始类型。我应该做些什么修改才能摆脱它?
TestUser代码看起来很难看。我错过了非常基本的东西吗?我不想使用Set<?>
由于 Nayn
答案 0 :(得分:3)
您可以返回ITest<?>
以消除警告,但可能您需要更强烈的类型:
public class TestFactory {
public static ITest<?> getInstance(int type) {
if(type == 1)
return new test1();
else if(type == 2)
return new test2();
else
throw new IllegalArgumentException("Unknown type");
}
public static <T> ITest<T> getInstance(Class<T> clazz) {
if(clazz == String.class)
return new test1();
else if(clazz == Integer.class)
return new test2();
else
throw new IllegalArgumentException("Unknown type");
}
}
答案 1 :(得分:0)
在您的情况下,Generics参数没有任何有意义的替代品实际上具有任何特定用途,但是您可以在方法签名中添加<Object>
或<?>
来摆脱警告。
我看到的示例代码的更大问题是,在命名类和方法时,您没有关注JCC。
答案 2 :(得分:0)
当你调用getInstance时,无法知道将返回哪种类型。
但是,您可以更改工厂方法的签名以使用泛型:
public <A> ITest<A> getInstance(Class<A> type)
{
}
答案 3 :(得分:0)
没有机会 - 除了压制警告本身。在Java中,通常不可能声明只有不同返回类型的方法。使用泛型并没有“逃避”。具有相同名称且返回不同类型的方法需要不同的参数签名(参见:重载)。
如果查看相应的字节代码,您会发现MethodHere
将返回一个Object。这称为类型擦除。通用参数仅供编译器用于检查/确保类型安全。
与往常一样 - 返回一个公共超类型并让方法调用者确定对象类型(就像在适配器模式中使用的那样)。