-项目类-
A类:
public class A {
public static void main(String[] args) {
D d = new D();
B.set(d);
d.add(new H()); //$ (correct error)
B.get().add(new H()); //! (no error)
}
}
B类:
public class B {
protected static C c;
public static C get() {
return B.c;
}
public static void set(C c)
B.c = c;
}
C类:
public abstract class C<T> {
protected ArrayList<T> array = new ArrayList<T>();
public void add(T element) {
this.array.add(element);
}
}
D类:
public class D extends C<G> {
//
}
E类:
public class E extends C<H> {
//
}
F级:
public abstract class F<T> {
//
}
G类:
public class G extends F<X> {
//
}
H 类:
public class H extends F<Y> {
//
}
-类别角色-
-
A
是主类 -
B
是一个存储对象引用的类 -
C
是一个定义对象数组的通用类 -
D
&E
延长C
不同类型 -
G
&H
延长F
不同类型
-逻辑问题-
在 A.main()
, //!
代表问题所在,//$
代表期望的行为。因为B.get()
返回抽象类型C
,向 array
添加非法元素是可以完成的(在本例中,由于 H
的 G
的扩展,只有 D
才合法时添加 C
)。
从B.get()
返回的对象的类型程序中未知(因为 B.c
可以表示类型 D
或类型 E
的对象),因此对 B
进行修改检查c
的类型并返回它或在 B.get()
的调用中自动转换它如果可能的话,这是理想的。
-问题编辑-
为了澄清起见,使用 ((D) B.get()).add(new H());
进行类型转换没有帮助,因为 B.c 持有的子类型未知。如果可以做类似((B.get().getClass()) B.get()).add(new H())
的事情,那会有帮助的。我选择的解决方案最好是更改或方法 B.get()
如果可能的话,而不是在主方法中。
为了进一步澄清,解决此问题的结果应该会导致错误,以防止在从 B.get()
引用时向数组中意外添加非法类型。 (//!
表示没有发生错误的位置,//$
表示发生错误的位置理应)。我愿意重写如何保存对 D
实例的引用和E
在B
if 以动态方式引用 C
的类型可以完成(输入 D
或类型 E
)可以完成。
最佳答案
泛型类型仅在编译时起作用。听起来你正试图让泛型实现动态类型安全,但由于删除,它们在这方面做得很糟糕。使用B
作为一个单例,其静态 c
千变万化的类型令人难以置信。您可以尝试保留 Class<?>
的映射至C<?>
在 B 中并在尝试调用 add
之前获取适当的一个,我猜。
另外,在 //$
您只是使用了错误的子类。
d.add(new G());
类型检查正确。
这就是我的意思:
public class A {
public static void main(String[] args) {
D d = new D();
B.put( G.class, d);
B.get( H.class ).add(new H()); // dynamic typing, but susceptible to null as written
d.add(new G()); //$ (no longer causes error)
}
}
public class B {
protected static Map< Class<?>, C<?> > mapC;
public static <T> C<T> get( Class<T> clsT ) {
return ( C< T > )mapC.get( clsT );
}
public static < T > void put(Class< T > clsT, C<T> c) {
mapC.put( clsT, c );
}
}
public abstract class C<Type> {
protected ArrayList<Type> array = new ArrayList<Type>();
public void add(Type element) {
this.array.add(element);
}
}
public class D extends C<G> {
//
}
public class E extends C<H> {
//
}
public abstract class F<Type> {
//
}
public class G extends F<String> {
//
}
public class H extends F<Integer> {
//
}
关于java - 用于获取和调用具有通用父级的子级的方法的编程返回类型或转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59686477/