简体   繁体   English

Java通用成员初始化

[英]Java generic member initialization

Suppose I have a Java class parameterized on that contains a private T _member. 假设我有一个参数化的Java类,其中包含一个私有的T _member。 I want to write a default constructor (no arguments), that somehow initializes my T _member to some known, type T specific value (like -1 for Integer, Float.MAX_VALUE for Float...). 我想写一个默认的构造函数(没有参数),它以某种方式将我的T _member初始化为一些已知的类型T特定值(对于Integer为-1,对于Float为Float.MAX_VALUE ......)。 Is that possible? 那可能吗? I tried new T(), but the compiler doesn't like that. 我尝试了新的T(),但编译器不喜欢这样。 Or do I do nothing, and the default constructor is guaranteed to be called for me? 或者我什么都不做,保证为我调用默认构造函数?

Because of type erasure , at runtime "there is no T". 由于类型擦除 ,在运行时“没有T”。

The way around it is to pass an instance of Class<T> into the constructor, like this: 解决它的方法是将Class<T>的实例传递给构造函数,如下所示:

public class MyClass<T> {

    T _member;

    public MyClass(Class<T> clazz) {
        _member = clazz.newInstance(); // catch or throw exceptions etc
    }

}

BTW, this is a very common code pattern to solve the issue of "doing something with T" 顺便说一下,这是一个非常常见的代码模式来解决“用T做事”的问题

It's not directly possible, since there's no way to guarantee T even has a default constructor. 它不是直接可能的,因为没有办法保证T甚至一个默认的构造函数。 You could conceivably do it using reflection with newInstance , however. 但是,你可以想象使用newInstance反射来做到这一点。 Just be sure to catch any exceptions that may be thrown. 请务必捕获可能引发的任何异常。

public class MyClass<T> {

    private T _member;

    public MyClass(Class<T> cls) {
        try {
            _member = cls.newInstance();
        } catch (InstantiationException e) {
            // There is no valid no-args constructor.
        }
    }
}

Every field in Java without an initializer expression is automatically initialized to a known default value. 没有初始化表达式的Java中的每个字段都会自动初始化为已知的默认值。 And yes, in this case it is a known value of type T -- null . 是的,在这种情况下,它是类型T的已知值 - null

In fact there is a way to do this, here's a link to answer on related SO question. 事实上, 一种方法可以做到这一点,这里有一个链接, 回答有关问题的SO。

Thus in fact your main question if there's a possibility to get Class of generic member at runtime? 因此,事实上你的主要问题是否有可能在运行时获得通用成员类? Yes, there is - using reflection. 是的,有 - 使用反射。

When I came over that answer about a year ago, I tested it and investigated reflection a little bit more. 大约一年前,当我回答这个问题时,我对它进行了测试并对反射进行了一些调查。 In fact, there were couple of cases when it didn't work as is (be ware of cases with inheritance), but in general it's wrong to claim this is impossible. 事实上,有几种情况它不能正常工作(具有继承的案件),但总的来说,声称这是不可能的是错误的。

However, I strongly do not suggest doing it this way. 但是,我强烈建议不要这样做。

EDIT. 编辑。 Surprisingly I found my own comment below that answer :) And in the next comment there's a link by author to the original article on generics' reflection. 令人惊讶的是,我在下面的答案中找到了我自己的评论:)在下一篇评论中,作者将链接到关于泛型反思的原始文章。

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

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