java - 用于获取和调用具有通用父级的子级的方法的编程返回类型或转换

标签 java generics casting abstract-class

-项目类-

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> {
    //
}

-类别角色-

  1. A是主类
  2. B是一个存储对象引用的类
  3. C是一个定义对象数组的通用类
  4. D & E延长C不同类型
  5. G & H延长F不同类型

-逻辑问题-

A.main() , //!代表问题所在,//$代表期望的行为。因为B.get()返回抽象类型C ,向 array 添加非法元素是可以完成的(在本例中,由于 HG 的扩展,只有 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 实例的引用和EB 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/

相关文章:

c++ - reinterpret_cast<char*>(p) 或 static_cast<char*>((void*)p)) 用于字节指针差异,哪个更好?

java - Spring AOP 切入点不适用于抽象方法

java - 在 Java 中过滤 XML 节点 | XSLT 或解析器

Java 非常不寻常的类路径问题

ios - 无法将类型 '[CustomObject]' 的值转换为预期参数类型 '[_]'

c# - 有没有办法将泛型类向下转换为具有派生 T 的实例?

java - 在 Java 中搜索两个 arrayList 索引之间的通用项

java - 如果将成员数据声明为原始数据类型,如果对象被声明为可序列化,值是否会被序列化?

mysql - 需要将 SQL 列从 varchar(255) 转换为 bigint(20)

java - 通过使用 java Field getType() 方法进行转换,将对象从一种类型转换为另一种类型