Java泛型成员初始化

6
假设我有一个参数化的Java类,其中包含一个私有的T _member。 我想写一个默认构造函数(无参数),以某种方式将我的T _member初始化为某个已知的特定类型T值(例如对于Integer为-1,对于Float为Float.MAX_VALUE ...)。 这可能吗? 我尝试了new T(),但编译器不喜欢那样做。还是我什么也不做,保证会为我调用默认构造函数?
4个回答

5
由于类型擦除,在运行时“不存在 T”。 解决方法是将Class<T>的实例传递到构造函数中,就像这样:
public class MyClass<T> {

    T _member;

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

}

顺便提一下,这是解决“对T执行某些操作”问题的非常常见的代码模式。


1
那个时髦的类有热闹的气氛。 :D 这是离题了,但我忍不住要说。 - Wug
3
你的意思是类型擦除,我理解没错吧?(如果运行时自我擦除就有点糟糕了;-)) - meriton
作为参数传递的类实例被称为类型标记 - hertzsprung

3

直接实现不可能,因为无法保证T甚至具有默认构造函数。但是,您可以使用反射和newInstance来实现。请确保捕获可能抛出的任何异常。

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.
        }
    }
}

你不能对 T 做任何操作。这个答案完全无效。请查看我的答案以了解原因。 - Bohemian
哎呀!你完全改了你的答案,然后复制粘贴我的答案在上面。你没有荣誉感吗? - Bohemian
我没有复制粘贴你的答案。我添加了我的第二和第三句话的例子。我已经为你的答案点赞了,朋友,没有恶意。 - Jon Newmuis
2
+1 是指出 T 可能没有默认构造函数。 - Louis Wasserman

3

Java中没有初始化表达式的每个字段都会自动初始化为已知的默认值。是的,在这种情况下,它是T类型的已知值 -- null


0

实际上有一种方法可以做到这一点,这里是一个链接answer相关的SO问题。

因此,实际上你的主要问题是是否有可能在运行时获取泛型成员的类?是的,可以使用反射。

当我大约一年前看到那个答案时,我测试了它并更深入地研究了反射。实际上,在某些情况下它不起作用(注意继承的情况),但总的来说,声称这是不可能的是错误的。

然而,我强烈不建议这样做。

编辑。令人惊讶的是,我发现了自己在那个答案下面的评论:)在下一个评论中,作者提供了一个关于泛型反射的原始文章的链接。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接