【问题标题】:Determine translated type for generics at runtime在运行时确定泛型的翻译类型
【发布时间】:2011-12-22 17:06:37
【问题描述】:

我的问题与here 完全相同。就是这样,我想用Java来做。

假设,我想创建一个列表为:

List<a_type> myList = new ArrayList<a_type>();

问题是a_type 是什么,是根据条件决定的。这两种可能的类型完全不相关,没有超类,但有共同的对象。如果我可以将类型存储在变量requiredType 中并将其用作List&lt;requiredType&gt;,我的问题将得到解决。我不确定我想要这个是贪婪、愚蠢还是无知,但情况就是这样。

虽然不重要,但解释了我为什么需要它的场景在here 中进行了解释。


PS:请不要提及类型擦除。请考虑现状。我本可以很好地自己在问题中提到它。如果您认为存在设计问题,请阅读情况here 并提出替代方案。

【问题讨论】:

  • 这在 Java 中是不可能的,我什至可以说如果你的设计需要这个,那就是有缺陷的......
  • @JarrodRoberson:如果您有更好的选择,请提出建议。 “您的设计有缺陷”似乎是互联网上任何地方发现的此类问题的最爱:) 有趣的是,这是一种情况,需要考虑解决方案。

标签: java generics runtime


【解决方案1】:

这在 Java 中是不可能的,因为类型擦除和泛型只限于编译时这一事实。

例如

List<Integer> integers = new ArrayList<Integer>();

在编译期间,类型擦除完成后变为

List integers = new ArrayList();

泛型只是告诉编译器的一种方式,该列表应该只处理 Integer 类型的对象,如果您在某处尝试添加 Integer 以外的其他内容以确保类型安全,请指出它.

【讨论】:

    【解决方案2】:

    我认为这样做的唯一有效(如果“有风险”)方法类似于:

         List<?> myList = new ArrayList<?> ();
    
         /* … */
    
         final Object o = myList.get (0);
    
         if (o instanceof OneType) {
               OneType o1 = (OneType)o;
               /* … */
         } else if (o instanceof OtherType) {
               OtherType o2 = (OtherType)o;
               /* … */
         } else {
               throw new RuntimeException ("unexpected type found in list…");
         }
    

    你可能想用@SuppressWarnings 乱扔代码

    可能更好的(?)想法是在这两种类型中至少实现一个“标记接口”(可能没有任何方法),并将其用作共性。

         public interface CanBeAddedToDualTypedList { };
         public class OneType implements CanBeAddedToDualTypeList { … };
         public class OtherType implements CanBeAddedToDualTypeList { … };
    
    
         List<CanBeAddedToDualTypedList> myList = 
                         new ArrayList<CanBeAddedToDualTypedList> ()
    

    编辑我还回答了您的相关问题,展示了针对特定情况使用通用接口的具体示例。

    【讨论】:

      【解决方案3】:

      Java 泛型在运行时不可用,因此不能使用 java

      在google上搜索“Type Erasure”,你会更明白。

      【讨论】:

      • 是的,知道这一点。这就是为什么我认为我在这里可能有点贪婪。但我想做的只是以安全的方式初始化我的通用列表。 :(
      • 不幸的是没有办法:(
      【解决方案4】:

      您可以存储 a_type.class 对象,而这对泛型没有帮助,它可用于添加额外的运行时类型检查 class.cast(...)

      泛型不支持运行时类型,泛型类型本身在运行时不存在。 C# 对每个通用类型都有一个运行时类List&lt;String&gt;List&lt;int&gt; 不同。在 java 中,List&lt;String&gt;List&lt;Integer&gt; 在运行时不会降级为 List

      AFAIK(从未尝试过)扩展泛型类将类型存储在反射class StringList extends List&lt;String&gt;{} 可访问的位置,StringList 记住用于扩展列表的泛型类型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-14
        • 1970-01-01
        • 2011-09-09
        相关资源
        最近更新 更多