具有显式类型构造函数的通用类

4

是否可以编写一个具有一个构造函数的通用类,该构造函数明确定义了其类的类型?

这是我的尝试:

import javax.swing.JComponent;
import javax.swing.JLabel;

public class ComponentWrapper<T extends JComponent> {

    private T component;

    public ComponentWrapper(String title) {
        this(new JLabel(title));  // <-- compilation error
    }

    public ComponentWrapper(T component) {
        this.component = component;
    }

    public T getComponent() {
        return component;
    }

    public static void main(String[] args) {
        JButton button = new ComponentWrapper<JButton>(new JButton()).getComponent();
        // now I would like to getComponent without need to cast it to JLabel explicitly
        JLabel label = new ComponentWrapper<JLabel>("title").getComponent();
    }

}
2个回答

5
你可以进行投射:
public ComponentWrapper(String title) {
    this((T) new JLabel(title));
}

由于通用信息不能用于某些实例,因此出现了这种情况。例如:
new ComponentWrapper() // has 2 constructors (one with String and one with Object since Generics are not definied).

该类本身无法预测这种用法,在这种情况下,将考虑最坏情况(没有通用信息)。


谢谢。我修改了我的问题以更好地解释我的意图。我想做的是 JLabel label = new ComponentWrapper("text").getComponent() - Michal Vician
这样做非常不安全。如果我执行 new ComponentWrapper<JButton>("SomeString"); 会怎么样呢?最好的情况是到处都会出现 ClassCastException... - Romain
new ComponentWrapper<JButton>("SomeString") 可能会导致编译错误。在运行时不会出现 ClassCastException - Michal Vician
@miso:这是你想要发生的事情,但不是编译器会做的事情。 - Romain
我只是在想为什么不允许这样的事情,因为如果你按照我在问题中建议的构造函数编写代码,那么编译器就有了所有信息,在编译时可以检查类型安全性。 - Michal Vician
在原始类型使用中,它将如何计算? - Francisco Spaeth

4

您当前的代码很容易导致无效状态(例如,包装了JLabelComponentWrapper<SomeComponentThatIsNotAJLabel>),这可能是编译器停止的原因。在这种情况下,您应该使用静态方法:

public static ComponentWrapper<JLabel> wrapLabel(final String title) {
    return new ComponentWrapper<JLabel>(new JLabel(title));
}

在很多方面,这将更加安全。


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