Java: Defining a generic method inside an anonymous class
Asked Answered
S

2

8

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.

Solo answered 9/4, 2017 at 18:39 Comment(4)
Please post the exact error message.Dagney
Why do you think you want to do this?Tweezers
This is the error (in Intellij): Error:(11, 18) java: cannot find symbol symbol: method setEnabled(boolean) location: variable x of type T.Solo
A good first step would have been to copy the method into a normal, named class and ensure it compiles there.Fu
S
10

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);
}
San answered 9/4, 2017 at 18:48 Comment(0)
A
11

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);
}
Anaglyph answered 9/4, 2017 at 18:45 Comment(0)
S
10

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);
}
San answered 9/4, 2017 at 18:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.