Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic class with explicitly typed constructor

Tags:

java

generics

Is it possible to write generic class with one constructor which explicitly defines type of its class?

Here is my attempt to do that:

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();
    }

}
like image 690
Michal Vician Avatar asked Jan 17 '23 06:01

Michal Vician


2 Answers

You could cast it:

public ComponentWrapper(String title) {
    this((T) new JLabel(title));
}

This is due to the Generic information, that could not be used for some instances. For example:

new ComponentWrapper() // has 2 constructors (one with String and one with Object since Generics are not definied).

The class itself cannot predict such use, in this case the worst case (no Generic info) is considered.

like image 133
Francisco Spaeth Avatar answered Jan 30 '23 05:01

Francisco Spaeth


Your current code can easily lead to invalid states (e.g. ComponentWrapper<SomeComponentThatIsNotAJLabel> that wraps a JLabel), and that's likely why the compiler stops you there. You should use a static method instead in this case:

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

Which would be much safer in many ways.

like image 21
Romain Avatar answered Jan 30 '23 04:01

Romain