简体   繁体   English

在运行时确定泛型的转换类型

[英]Determine translated type for generics at runtime

My question is exactly similar to the one here . 我的问题与这里的问题完全相似。 Just that, I want to do it in Java. 就是这样,我想用Java做。

Suppose, I want to crate a list as: 假设,我想列出一个列表:

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

The problem is that what a_type would be, is decided on the base of a condition. 问题是a_type是什么,是根据条件决定的。 The two possible types are totally unrelated, having no superclass but Object in common. 两种可能的类型是完全不相关的,没有超类但是Object是共同的。 My problem will be solved if I can store the Type in a variable requiredType and use it as List<requiredType> . 如果我可以将Type存储在变量requiredType并将其用作List<requiredType>我的问题将得到解决。 I am not sure if I'm just being greedy or foolish or ignorant in wanting this, but that's the situation. 我不确定我是不是只是贪婪,愚蠢或无知,但这就是情况。

Although not important, but the scenario that explains why I need it is explained here . 虽然不重要,但这里解释了解释我为什么需要它的场景。


PS: Please do not mention type-erasure. PS:请不要提及类型擦除。 Kindly consider the situation as it is. 请考虑这种情况。 I could have very well myself mentioned it in the question. 我可以很好地在问题中提到它。 If you think there are design issues, kindly read the situation here and suggest alternatives. 如果您认为存在设计问题,请仔细阅读此处的情况并提出替代方案。

That's not possible in Java, because of the type-erasure and due to the fact that generics is only limited to compiletime. 这在Java中是不可能的,因为类型擦除并且由于泛型仅限于编译时间。

eg 例如

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

During compiletime, when the the type-erasing is done becomes 在编译期间,当完成类型擦除时

List integers = new ArrayList();

The generics is only a way to tell the compiler, that the list should only deal with objects of type Integer , and let's it point it out if you have somewhere tried to add something other than Integer for type safety. 泛型只是告诉编译器的一种方式,列表应该只处理Integer类型的对象,如果你有某个地方试图为了类型安全而添加除Integer以外的东西,那就让它指出来。

The only effective (if “risky”) way I could see to do so, would be something akin to: 我能看到的唯一有效(如果“冒险”)方式,将类似于:

     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…");
     }

You will probably want to litter that code with @SuppressWarnings 您可能希望使用@SuppressWarnings乱丢该代码

Possibly a better(?) idea would be to implement at least a “marker interface” (without perhaps any methods) in both types, and use that as the commonality. 可能更好(?)的想法是在两种类型中至少实现“标记接口”(没有任何方法),并将其用作通用性。

     public interface CanBeAddedToDualTypedList { };
     public class OneType implements CanBeAddedToDualTypeList { … };
     public class OtherType implements CanBeAddedToDualTypeList { … };


     List<CanBeAddedToDualTypedList> myList = 
                     new ArrayList<CanBeAddedToDualTypedList> ()

Edit I also put an answer on your related question, showing a concrete example of using a common interface for that specific case. 编辑我还回答了您的相关问题,显示了针对该特定案例使用通用界面的具体示例。

Java generic are not available at runtime so not possible with java Java泛型在运行时不可用,因此java无法实现

Search for "Type Erasure" on google and you will understand it better. 在谷歌上搜索“类型擦除”,你会更好地理解它。

You can store the a_type.class object while that wont help you with generics, it can be used to add additional runtime type checks class.cast(...) . 您可以存储a_type.class对象,而不会帮助您使用泛型,它可以用于添加额外的运行时类型检查class.cast(...)

Generics do not support runtime typing, the generic type itself does not exist at runtime. 泛型不支持运行时类型,泛型类型本身在运行时不存在。 C# has a runtime class for each Generic type List<String> is different from List<int> . C#为每个通用类型都有一个运行时类List<String>List<int> In java this is not the case both List<String> and List<Integer> degrade to List at runtime. 在java中,这不是List<String>List<Integer>在运行时降级为List情况。

AFAIK (never tried it) extending a Generic class stores the type somewhere accessible to reflection class StringList extends List<String>{} , the StringList remembers the Generic type used to extend List. AFAIK(从未尝试过)扩展Generic类存储类型可以访问的类型class StringList extends List<String>{} ,StringList记住用于扩展List的Generic类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM