java - Java 中的默认/Mixin 泛型

标签 java generics

我想知道是否可以在类初始化时替换泛型类型(无需继承)。 案例如下。 我的模块中有一堆通用的 Actor + 构建器类,并将其分发给想要在我的团队中使用它的人,同时保持 Actor 和流畅界面的入口点通用。

需求是人们如何提供自己的构建器(而不是扩展)来完成他们想要的事情。

当前状态:

class MessageBuilder {
    public MessageBuilder msg(String msg) {
        //do something
    }
}

class Actor {        
    public MessageBuilder newMessage() {
        return new MessageBuilder();
    }
}

class Main {            
    @Test
    public void testActor() {
        Actor actor = new Actor();
        actor.newMessage().msg("sss").send();
    } 
}

所需状态:

class MessageBuilder{    
    public MessageBuilder msg(String msg) {
        //do something
    }

    //more fluent api...    
}

// project specific - dont want to extend from generic one as this should be contains its own fluent interface
class MyCustomMessageBuilder {
    public MyCustomMessageBuilder rawstr(String rawstr) {
        //do something
    }
}

class Actor<T> {
    public T newMessage() {
        return (T)builderFactory.getInstance();
    }
}

class Main {            
    @Test
    public void testActor() {
        Actor<MyCustomMessageBuilder> actor = new Actor(BuilderFactory);
        actor.newMessage().rawstr("sss").send();
    } 
}

最佳答案

如果没有一些已知的技巧,这是不可能的。

首先,Java 用 type erasure 实现泛型( more information on type erasure ),因此编译器将:

Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.

实际上,这意味着 Actor<Builder1>Actor<Builder2>编译后是完全相同的类。在这两种情况下,newMessage实现如下:

class Actor {
    public Object newMessage() {
        ...
    }
}

newMessage 是不可能的根据类型参数有不同的实现, newMessage 是不可能的询问 T 的类型因为它被删除了。

话虽如此,您可以传入类型信息:

class Actor<T> {
    private Class<T> klass;

    public Actor(Class<T> klass) {
        this.klass = klass;
    }

    public T newMessage() {
        return klass.newInstance();
    }
}

class Main {
    @Test
    public void testActor() {
        Actor<MyCustomMessageBuilder> actor = new Actor<>(MyCustomMessageBuilder.class);
        actor.newMessage().rawstr("sss").send();
    }
}

关于java - Java 中的默认/Mixin 泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58478899/

相关文章:

c# - C# 值类型的直接比较

带有 super 关键字的 Java 泛型方法

swift - 使用 Swift Optional 类型的奇怪行为

generics - Kotlin泛型 “in”和 “out”在继承中的用法

java - 如何获取redis中特定hash下的所有key和value?

java - Spring Batch writer 从下一行追加数据

Java for 循环,包含多个条件并递增多个整数

scala - 如何构建泛型类型的匿名实例?

java - JSP异常隐式对象

java - hibernate 更新查询中的值未更新