您是否有充分的理由可以在Java类中拥有或不具有内部接口?

Ale*_*lls 0 java interface inner-classes

您是否有充分的理由可以在Java类中拥有或不具有内部接口?(就像你会内心一样).我无法找到谷歌的确切答案,但看起来好像你不能像使用内部类一样嵌入界面.我的猜测是Java创建者没有看到使其成为可能的一个很好的理由,所以它不是,但也许有很好的理由?

例如我无法编译(这是一大类)

package buttonGetSourceObject;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class ClassWithButton implements ActionListener, ButtonOwner{

    private String objectName = "";

    public ClassWithButton(String string) {
        objectName = string;
        JFrame f = new JFrame();
        JPanel p = new JPanel();
        MyJButton b = new MyJButton(this,"Press This Button for Name of Owner of Button");
        b.addActionListener(this);
        f.add(p);
        p.add(b);
            f.pack();
        f.setVisible(true);


    }

    public static void main(String[] args){
        ClassWithButton c = new ClassWithButton("object1name");
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        ((ButtonOwner)((MyJButton)arg0.getSource()).getOwner()).printInstanceName();

    }


    public interface ButtonOwner {
        public void printInstanceName();
    }


    private class MyJButton extends JButton {

        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        Object owner = null;

        public Object getOwner() {
            return owner;
        }

        public void setOwner(Object owner) {
            this.owner = owner;
        }

        public MyJButton(Object o, String string){
            owner = o;
            this.setText(string);
        }
    }


   @Override
    public void printInstanceName() {

        System.out.println(this);

    }

    public String getObjectName() {
        return objectName;
    }

    public void setObjectName(String objectName) {
        this.objectName = objectName;
    }

    public String toString(){
        return this.getObjectName();
    }

} //end
Run Code Online (Sandbox Code Playgroud)

编译器似乎根本不认识内部接口"ButtonOwner"

Fri*_*Guy 5

因为它是一个内部类,所以必须使用您正在扩展的类的全名(例如,使用ClassWithButton.ButtonOwner而不是仅使用ButtonOwner):

public class ClassWithButton implements ActionListener, ClassWithButton.ButtonOwner
Run Code Online (Sandbox Code Playgroud)

但是,这将无法正常工作,因为您正在扩展内部接口:

检测到周期:类型ClassWithButton无法扩展/实现自身或其自己的成员类型之一

至于为什么类不能实现内部接口,对上述问题的评论表明它可能是因为:

类加载如何工作.对其他类的正常引用是懒惰加载的,但在加载类本身之前会自动加载外部类,超类和实现的接口.当你的外部类实现一个内部接口并且该构造本身有效时,在运行时加载类时,你会在类加载器中得到一个StackOverflowError ...

  • +1这是实际回答OP的"为什么?"问题的唯一答案.其他答案简单地说"编译器说没有" (2认同)
  • (另一个挑剔 - 嵌套接口不是"内部".根据JLS,嵌套接口是隐式的"静态".) (2认同)