Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 用于获取和调用具有泛型父级的子级的方法的编程返回类型或强制转换 -项目类-_Java_Generics_Casting_Abstract Class - Fatal编程技术网

Java 用于获取和调用具有泛型父级的子级的方法的编程返回类型或强制转换 -项目类-

Java 用于获取和调用具有泛型父级的子级的方法的编程返回类型或强制转换 -项目类-,java,generics,casting,abstract-class,Java,Generics,Casting,Abstract Class,A类: 公共A类{ 公共静态void main(字符串[]args){ D=新的D(); B.set(d); d、 添加(新H());//$(更正错误) B.get().add(新的H());/!(无错误) } } B类: 公共B类{ 保护静电; 公共静态C get(){ 返回B.c; } 公共静态无效集(C) B.c=c; } C类: 公共抽象类C{ 受保护的ArrayList数组=新的ArrayList(); 公共无效添加(T元素){ this.array.add(元素); } } D

A类:

公共A类{
公共静态void main(字符串[]args){
D=新的D();
B.set(d);
d、 添加(新H());//$(更正错误)
B.get().add(新的H());/!(无错误)
}
}
B类:

公共B类{
保护静电;
公共静态C get(){
返回B.c;
}
公共静态无效集(C)
B.c=c;
}
C类:

公共抽象类C{
受保护的ArrayList数组=新的ArrayList();
公共无效添加(T元素){
this.array.add(元素);
}
}
D类:

公共类D扩展了C{
//
}
E类:

公共类E扩展了C{
//
}
F类:

公共抽象类F{
//
}
G类:

公共类G扩展了F{
//
}
H类:

公共类H扩展了F{
//
}
-班级角色-
  • A
    是主类
  • B
    是存储对象引用的类
  • C
    是定义对象数组的通用类
  • D
    E
    使用不同类型扩展
    C
  • G
    H
    使用不同类型扩展
    F
  • -逻辑问题- 在
    A.main()表示问题所在的位置,
    /$
    表示所需的行为。由于
    B.get()
    返回抽象类型
    C
    ,因此可以将非法元素添加到
    array
    中(在本例中,由于
    D
    C
    的扩展,只有
    G
    是合法的,所以添加
    H

    程序中不知道从
    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()
    引用时向数组添加非法类型(
    /!
    表示没有错误发生的位置,
    /$
    表示错误发生的位置)。我愿意重新编写如何在
    B
    中保存对
    D
    E
    实例的引用,前提是可以实现对
    C
    类型的动态引用(type
    D
    或type
    E
    )。听起来好像你在试图让泛型做动态类型安全,这是他们因为擦除而做得很糟糕的事情。使用
    B
    作为一个静态
    c
    类型不断变化的单身汉是非常尴尬的。我想,您可以尝试在B中保留从
    Class
    C
    的映射,并在尝试调用
    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> {
        //
    }
    
    公共A类{
    公共静态void main(字符串[]args){
    D=新的D();
    B.put(G级,d级);
    B.get(H.class).add(new H());//动态类型,但在编写时易受null的影响
    d、 添加(新G());//$(不再导致错误)
    }
    }
    公共B级{
    受保护的静态映射mapC;
    公共静态C get(类clsT){
    返回(C)mapC.get(clsT);
    }
    公开静态无效认沽权(类别clsT,C){
    mapC.put(clsT,c);
    }
    }
    公共抽象类C{
    受保护的ArrayList数组=新的ArrayList();
    公共void添加(类型元素){
    this.array.add(元素);
    }
    }
    公共类D扩展C{
    //
    }
    公共类E扩展C{
    //
    }
    公共抽象类F{
    //
    }
    公共类G扩展F{
    //
    }
    公共类H扩展F{
    //
    }
    
    当您将
    C
    作为没有类型参数的
    B
    中静态字段的类型时,您的程序总是会有危险的潜在类型错误。
    D
    应该与
    G
    s而不是
    H
    s一起工作。基本上是“什么是原始类型,为什么我们不应该使用它?”的精心复制