Java 如何解决“问题”;“未经检查的铸件”;来自不同接口的泛型
未选中的演员阵容:“zzz.szi.m.Something1”到“T” 我在运行“mvn包”时收到警告 //在(T)中添加了铸件,但结果相同Java 如何解决“问题”;“未经检查的铸件”;来自不同接口的泛型,java,generics,casting,Java,Generics,Casting,未选中的演员阵容:“zzz.szi.m.Something1”到“T” 我在运行“mvn包”时收到警告 //在(T)中添加了铸件,但结果相同 当您将方法设置为泛型时,我不希望出现警告,这意味着调用方可以控制类型参数。调用方始终可以提供任何满足任何限制的内容,而您没有限制。调用方可以提供Integer、Object或Foo,此方法需要返回该类型的实例 然而,根据编译器的说法,这与方法逻辑中的条件无关。它不能保证您返回的内容与类型参数完全匹配,而类型参数正是编译器试图说的 您的方法在这里不能是泛型的
当您将方法设置为泛型时,我不希望出现警告,这意味着调用方可以控制类型参数。调用方始终可以提供任何满足任何限制的内容,而您没有限制。调用方可以提供
Integer
、Object
或Foo
,此方法需要返回该类型的实例
然而,根据编译器的说法,这与方法逻辑中的条件无关。它不能保证您返回的内容与类型参数完全匹配,而类型参数正是编译器试图说的
您的方法在这里不能是泛型的。如果所有SomethingX
类都继承自基类或接口,则让方法返回该类型,否则它必须是对象
。如果您需要调用所有SomethingX
类都具有的一个特定方法,请提取一个新接口并让您的方法返回该类型
如果没有任何公共接口,但必须对返回的对象调用特定的方法,则将此方法之外的条件逻辑放入调用代码中,或者在返回对象之前对其进行方法调用
private Object get() throws Exception {
Object m;
if (/*some condition*/) {
Something1 s1 = new Something1();
s1.s1Method();
m = s1;
}
else if (/*some condition*/) {
Something2 s2 = new Something2();
s2.s2Method();
m = s2;
}
else {
Something3 s3 = new Something3();
s3.s3Method();
m = s3;
}
return m;
}
当您将方法设置为泛型时,这意味着调用方可以控制类型参数。调用方始终可以提供任何满足任何限制的内容,而您没有限制。调用方可以提供
Integer
、Object
或Foo
,此方法需要返回该类型的实例
然而,根据编译器的说法,这与方法逻辑中的条件无关。它不能保证您返回的内容与类型参数完全匹配,而类型参数正是编译器试图说的
您的方法在这里不能是泛型的。如果所有SomethingX
类都继承自基类或接口,则让方法返回该类型,否则它必须是对象
。如果您需要调用所有SomethingX
类都具有的一个特定方法,请提取一个新接口并让您的方法返回该类型
如果没有任何公共接口,但必须对返回的对象调用特定的方法,则将此方法之外的条件逻辑放入调用代码中,或者在返回对象之前对其进行方法调用
private Object get() throws Exception {
Object m;
if (/*some condition*/) {
Something1 s1 = new Something1();
s1.s1Method();
m = s1;
}
else if (/*some condition*/) {
Something2 s2 = new Something2();
s2.s2Method();
m = s2;
}
else {
Something3 s3 = new Something3();
s3.s3Method();
m = s3;
}
return m;
}
T
由编译器查看该方法调用的上下文来解析。如果调用的结果要分配给类型为XXX
的变量,则编译期间T
将替换为XXX
,以检查其余代码的逻辑
问题代码打破了这种约定,因为方法代码似乎控制着返回的类型,因此它通常无法就要实例化的类做出正确的选择。这就是为什么这个演员是不安全的
解决此问题的一种方法是将控件返回到调用代码。例如,get()
方法可以接受指示要返回的类型的类对象,并使用class.newInstance
创建该对象,而不必处理相应的选中异常,并且请求的类可能没有无参数构造函数:
private <T> T get(Class<? extends T> class) {
try {
return class.newInstance();
} catch (Exception ex) {
// handle the exception apropiately
}
}
问题仍然是,在对象实例化之前还是之后,您是否有子类不可知的公共代码添加到
get
的主体中,以使此方法值得使用,否则您最好只在每个if-else中调用相应的子类构造函数(即newsomething1()
,newsomething2()
etc)。编译器通过查看该方法调用的上下文来解析T
。如果调用的结果要分配给类型为XXX
的变量,则编译期间T
将替换为XXX
,以检查其余代码的逻辑
问题代码打破了这种约定,因为方法代码似乎控制着返回的类型,因此它通常无法就要实例化的类做出正确的选择。这就是为什么这个演员是不安全的
解决此问题的一种方法是将控件返回到调用代码。例如,get()
方法可以接受指示要返回的类型的类对象,并使用class.newInstance
创建该对象,而不必处理相应的选中异常,并且请求的类可能没有无参数构造函数:
private <T> T get(Class<? extends T> class) {
try {
return class.newInstance();
} catch (Exception ex) {
// handle the exception apropiately
}
}
问题仍然是,在对象实例化之前还是之后,您是否有子类不可知的公共代码添加到
get
的主体中,以使此方法值得使用,否则您最好只在每个if-else中调用相应的子类构造函数(即newsomething1()
,newsomething2()
etc)。为什么它需要是通用的?为什么这个方法不能只返回对象
?您是否在寻找实例
?因为当我返回“Object”时,调用function@NicholasK不我需要返回一个与某个接口兼容的对象,但是每个类可以实现不同的接口如果Something3
被传递到您的泛型方法中,那么预期的输出是什么?除了上面提出的问题外,请提供一个带有预期输出的示例输入。为什么需要是通用的?为什么这个方法不能只返回对象
?您是否在寻找实例
?因为当我返回“Object”时,我得到的是不匹配的
Something some;
if (/* condition 1 */) {
some = get(Something1.class);
} else if (/* condition 2 */) {
some = get(Something2.class);
} ...