Java: 在匿名 class 中定义泛型方法

Java: Defining a generic method inside an anonymous class

以下 java 代码工作正常。

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

如果将方法更改为其通用形式,程序将失败。

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

为什么会失败?如何在匿名 class 中定义泛型方法?

这个问题是为了学习目的。

T的擦除是Object,没有setEnabled。如果你给它一个 JComponent 的边界,它就会工作,它定义了 setEnabled:

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

T 泛型并未明确派生自 class 或接口。所以它来自 ObjectObject 没有 setEnabled() 方法。

如果您想使用泛型,您可以指定一个 java.swing 具有此方法的基类型。例如: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);
}