不在泛型类

时间:2016-10-29 10:15:59

标签: java generics inheritance

想象一下这样的代码:

public class Value<T> {
    private T value;

    public Value(T value) {
        this.value = value;
    }

    public int size() {
        return sizeOf(value);
    }

    private int sizeOf(int value) {
        return Integer.BYTES;
    }

    private int sizeOf(String value) {
        return value.length() * Character.BYTES;
    }
}

和某处(例如main

Value<String> value = new Value<String>("hello");

问题是代码无法编译,因为我没有实现sizeOf(T value)但是我不明白为什么编译器会抱怨---它看到我只使用它<T=String> 即可。如果我实现通用sizeOf(T value),它将优先(如此处Java generics (template) specialization possible (overriding template types with specific types)所述)

请注意,那里提出的解决方案(具有StringValue子类)在我的情况下并不真正适用,因为我已经有一些我正在使用的子类,所以我需要创建许多额外的类(按类型划分的次数)

enter image description here

但我更喜欢更直接的东西,比如这个

enter image description here

2 个答案:

答案 0 :(得分:2)

你必须声明sizeOf(T value)因为T可以是任何类型,所以为了维护类型controll,编译器需要&#34;通用&#34; sizeOf方法的版本,可以预示任何可能的类型。

想想如果你会使用类似new Value<List<Object>>(new ArrayList<Object>).size()之类的东西会发生什么 - 当你没有专门用于返回集合大小的方法时会发生什么?

问题是,在运行时,泛型类型被删除,因此JVM不知道应该使用重载方法。在此处查看有关类型擦除的更多信息。 https://docs.oracle.com/javase/tutorial/java/generics/erasure.html

答案 1 :(得分:2)

无法为size()提供实施。你的代码是双重调度模式的一半,但是一直无法进行,因为你无法要求像String这样的类型来实现size()

一种方法是在构造上要求尺寸代码:

public class Value<T> {
    private T value;
    private Function<T, Integer> size;

    public Value(T value, Function<T, Integer> size) {
        this.value = value;
        this.size;
    }

    public int size() {
        return size.apply(value);
    }
}

例如创建Value<String>

 Value<String> val = new Value("foo", s -> s.length() * Character.BYTES)

或者如果不起作用,请对支持的类型使用instanceof

public int size() {
    if (value instanceof Integer)
        return Integer.BYTES;
    if (value instanceof String)
        return ((String)value).length() * Character.BYTES;
    // other supported types
    throw new IllegalStateException();
}