The following java code works fine.
public static void main(String[] arg){
JPanel p = (new JPanel());
p.add( new Object(){
JButton f(JButton x){
x.setEnabled(false);
return x;
}}.f(new JButton("B")) );
JFrame w = new JFrame("W");
w.add(p);
w.pack();
w.setVisible(true);
}
If the method is changed to its generic form the program fails.
public static void main(String[] arg){
JPanel p = (new JPanel());
p.add( new Object(){
<T> T f(T x){
x.setEnabled(false);
return x;
}}.f(new JButton("B")) );
JFrame w = new JFrame("W");
w.add(p);
w.pack();
w.setVisible(true);
}
Why does it fail? How can you define generic methods within an anonymous class?
This question is for learning purposes.
T's erasure is Object, which does not have setEnabled. It works if you give it a bound of JComponent, which definessetEnabled:
public static void main(String[] arg) {
JPanel p = (new JPanel());
p.add( new Object(){
<T extends JComponent> T f(T x){
x.setEnabled(false);
return x;
}}.f(new JButton("B")) );
JFrame w = new JFrame("W");
w.add(p);
w.pack();
w.setVisible(true);
}
The T generic doesn't derive explicitly from a class or an interface. So it derives from Objectand Object has no setEnabled() method.
If you want to use generic, you could specify a java.swing base type that has this method. For example : javax.swing.AbstractButton.
public static void main(String[] arg){
JPanel p = (new JPanel());
p.add( new Object(){
<T extends AbstractButton> T f(T x){
x.setEnabled(false);
return x;
}}.f(new JButton("B")) );
JFrame w = new JFrame("W");
w.add(p);
w.pack();
w.setVisible(true);
}