V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
abcbuzhiming
V2EX  ›  Java

Java 就完全没有办法给泛型属性一个初始化的值吗?

  •  
  •   abcbuzhiming · 2021-02-03 23:58:13 +08:00 · 3227 次点击
    这是一个创建于 1149 天前的主题,其中的信息可能已经有所发展或是发生改变。
    一个类,含有一个泛型属性 T,我尝试了几乎所有的办法,都不能再这个类生成对象的时候就给这个 T 一个默认值。搜了一圈,英文网站上说这是无法做到的???
    14 条回复    2021-02-06 13:44:57 +08:00
    sagaxu
        1
    sagaxu  
       2021-02-03 23:59:59 +08:00 via Android
    可以初始化为 null
    codehz
        2
    codehz  
       2021-02-04 00:02:44 +08:00
    类型擦除了,所以拿不到类型信息,自然无法初始化,变通的方法就是加一个 Class<T> clazz 的参数(
    chendy
        3
    chendy  
       2021-02-04 00:08:28 +08:00
    类型擦除,拿不到 T 的类型,无法设置
    zpxshl
        4
    zpxshl  
       2021-02-04 00:09:05 +08:00 via Android
    可以的吧。用反射找到 t 真实类型,反射生成对应对象
    yeqizhang
        5
    yeqizhang  
       2021-02-04 00:49:40 +08:00 via Android
    想了解下为什么想要设置一个默认值?
    zhzy0077
        6
    zhzy0077  
       2021-02-04 01:09:44 +08:00
    这几乎是唯一一种做到的方法:

    import java.lang.reflect.*;

    class Main {
    public static void main(String args[]) throws Exception {
    var baz = new Foo<Baz>() {};
    System.out.println(baz.bar);
    }
    }

    class Baz {

    }

    class Foo<T> {
    T bar;

    public Foo() throws Exception {
    Type actualTypeArgument = ((ParameterizedType)this.getClass()
    .getGenericSuperclass())
    .getActualTypeArguments() [0];

    System.out.println(actualTypeArgument);

    Class<T> clazz = (Class<T>) actualTypeArgument;
    bar = clazz.newInstance();
    }
    }

    但是代价是必须在所有初始化的地方这么写 new Foo<Baz>() {} 而且 newInstance 也会假设一定有个无参构造函数。
    最有名的使用场景就是 fastjson 的 TypeReference 了, fastjson 为了在运行时拿到泛型的信息,就通过这个传进来的 https://github.com/alibaba/fastjson/blob/master/src/main/java/com/alibaba/fastjson/TypeReference.java

    你这个场景下其实构造函数传一个 Class<T>进来会更直接一点
    EminemW
        7
    EminemW  
       2021-02-04 09:11:16 +08:00 via iPhone
    先说为什么要这么做
    Takamine
        8
    Takamine  
       2021-02-04 09:34:03 +08:00 via Android
    你既然想给他初始值,那他就初始化时就是有类型的了,这为啥又要用泛型呢。
    Jooooooooo
        9
    Jooooooooo  
       2021-02-04 10:16:11 +08:00
    具体说说场景, 感觉不是用泛型的地方
    abcbuzhiming
        10
    abcbuzhiming  
    OP
       2021-02-04 16:00:21 +08:00
    @yeqizhang
    @EminemW
    @Jooooooooo

    因为这玩意如果不初始化,那么序列化为 json 后就是一个 null,因为某些前端限制,很难处理 null,它们希望这个东西至少序列化是个 {}
    palmers
        11
    palmers  
       2021-02-04 16:44:54 +08:00
    有初始值 不就有类型了吗?
    sydra
        12
    sydra  
       2021-02-04 16:46:06 +08:00
    @abcbuzhiming 在反序列化的接口里面增加一个空判断就可以了
    Elroooo0Y
        13
    Elroooo0Y  
       2021-02-04 22:15:34 +08:00
    @abcbuzhiming
    这很简单啊 重写 getResult 方法 返回一个空对象
    LGA1150
        14
    LGA1150  
       2021-02-06 13:44:57 +08:00 via Android
    典型的 XY 问题
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5880 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 02:13 · PVG 10:13 · LAX 19:13 · JFK 22:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.