【问题标题】:Statements in anonymous class declaration匿名类声明中的语句
【发布时间】:2018-07-04 23:43:30
【问题描述】:

我正在阅读 oracle 文档中的匿名课程教程 (https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html)

我复制了教程中使用的代码。(注释 Statement1 和 Statement2 由我附加):

public class HelloWorldAnonymousClasses {

    interface HelloWorld {
        public void greet();
        public void greetSomeone(String someone);
    }

    public void sayHello() {

        class EnglishGreeting implements HelloWorld {
            String name = "world";
            public void greet() {
                greetSomeone("world");
            }
            public void greetSomeone(String someone) {
                name = someone;
                System.out.println("Hello " + name);
            }
        }

        HelloWorld englishGreeting = new EnglishGreeting();

        HelloWorld frenchGreeting = new HelloWorld() {
            String name = "tout le monde"; //Statement1
            public void greet() {
                greetSomeone("tout le monde");
            }
            public void greetSomeone(String someone) {
                name = someone;
                System.out.println("Salut " + name);
            }
        };

        HelloWorld spanishGreeting = new HelloWorld() {
            String name = "mundo"; //Statement2
            public void greet() {
                greetSomeone("mundo");
            }
            public void greetSomeone(String someone) {
                name = someone;
                System.out.println("Hola, " + name);
            }
        };
        englishGreeting.greet();
        frenchGreeting.greetSomeone("Fred");
        spanishGreeting.greet();
    }

    public static void main(String[] args) {
        HelloWorldAnonymousClasses myApp =
            new HelloWorldAnonymousClasses();
        myApp.sayHello();
    }            
}

教程继续解释: 匿名类表达式由以下内容组成:

  1. 新的运算符

  2. 要实现的接口或要扩展的类的名称。在本例中,匿名类实现了 HelloWorld 接口。

  3. 包含构造函数参数的括号,就像普通的类实例创建表达式一样。注意:当你实现一个接口时,没有构造函数,所以你使用一对空括号,如本例所示。

  4. 一个主体,它是一个类声明主体。 更具体地说,在正文中,允许声明方法,但不允许声明。

我被这点弄糊涂了。 4 以上。它说匿名类声明主体中不允许使用语句,但我可以看到其中使用的语句。 (我把 cmets Statement1 和 Statement2 放在了突出显示它们)。

您能否解释一下本教程从第 1 点开始想要传达的内容。 4?

提前致谢。

【问题讨论】:

  • 不是语句而是实例变量定义和初始化
  • 这些是字段声明,也应该是private,这有助于消除您的困惑。

标签: java anonymous-class


【解决方案1】:

Statements are not allowed 表示以下任何一项都是不允许的。

  • 赋值表达式 (aValue = 8933.234;)
  • 任何使用 ++ 或 -- (aValue++;)
  • 方法调用 (System.out.println("Hello World!");)
  • 对象创建表达式 (Bicycle myBike = new Bicycle();)

但是this 文档也这么说,

请注意,您可以在匿名类中声明以下内容:

  • 字段
  • 额外的方法(即使它们没有实现超类型的任何方法)
  • Instance initializers
  • 本地类
    HelloWorld spanishGreeting = new HelloWorld() {

        String name = "mundo"; //Statement2

        double aValue = 0.0;

        String s = "Hi"; //instance variable initializers are allowed

       // assignment statement
        aValue = 8933.234; // not allowed

        // increment statement
        aValue++; // not allowed

        // method invocation statement
        System.out.println("Hello World!"); // not allowed

        // object creation statement
        Bicycle myBike = new Bicycle(); //instance variable initializers are allowed

        public void greet() {
            greetSomeone("mundo");
        }
        public void greetSomeone(String someone) {
            name = someone;
            System.out.println("Hola, " + name);
        }
    };

希望这会有所帮助。

【讨论】:

  • 不允许:对象创建表达式 (Bicycle myBike = new Bicycle();) 但您创建了一个带有 //allowed 注释的 String 对象。这令人困惑。
  • @miraclefoxx :我正在更新答案。抱歉耽搁了。
  • 它在我看来仍然很矛盾。希望有一个简短的解释
  • @miraclefoxx :这可能会有所帮助。 programcreek.com/2011/10/java-class-instance-initializers
  • @tharindu_DG:感谢您的解释。据我了解,无论是普通的还是匿名的,任何类声明都是如此。我说的对吗?
【解决方案2】:

您对statement 和field declaration 感到困惑。正如@sidgate 评论中提到的,它不是声明,而是实例定义和初始化。

为了更清楚地理解它 试着写一些像

这样的语句
HelloWorld frenchGreeting = new HelloWorld() {
            String name = "tout le monde"; //Statement1
            System.out.print("this is a statement");// it wont compile
            public void greet() {
                greetSomeone("tout le monde");
            }
            public void greetSomeone(String someone) {
                name = someone;
                System.out.println("Salut " + name);
            }
        };

【讨论】:

  • 那么这个“匿名类的主体禁止声明”是否仅仅意味着您不能将语句放在方法或初始化块之外?这适用于任何 Java 类,那么为什么要明确提及匿名类呢?
  • @miraclefoxx 你说得对,它适用于任何课程,而且他们只为匿名课程突出显示它有点令人困惑。我会猜他们这样做是因为匿名类看起来有点像代码块,因此您可能希望能够在其中放入语句。
【解决方案3】:

这就像晚了 3 年,但只是换一种方式来理解。匿名类的主体与任何其他顶级类的主体一样。

类中只能有成员,即变量(带或不带初始化)、方法和初始化块。

任何语句只能出现在方法或初始化块内,不能单独出现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-15
    • 2019-06-05
    • 1970-01-01
    • 1970-01-01
    • 2018-09-04
    • 1970-01-01
    • 2018-10-16
    • 1970-01-01
    相关资源
    最近更新 更多