43

この段階で、Java で根本的に新しい構文に遭遇することになるとは想像もしていませんでしたが、見よ、私は何かに遭遇しました:

正確なコンテキストと、以下のコードが何をすべきかはかなり無関係です - ある種のコンテキストを提供するためだけに存在します。

IT Mill Toolkit でイベントを合成的に作成しようとしているので、次のような行を書きました。

buttonClick(new Button.ClickEvent(button));

しかし、Eclipse から次のエラー メッセージが表示されます。

タイプ Button の囲んでいるインスタンスにアクセスできません。タイプ Button の囲んでいるインスタンスで割り当てを修飾する必要があります (egxnew A() ここで、x は Button のインスタンスです)。

上記の行を次のように書き直すと、もう文句はありません。

buttonClick(button.new ClickEvent(button)); // button instanceof Button

それで、私の質問は次のとおりです。後者の構文は正確には何を意味し、最初のスニペットが機能しないのはなぜですか? Java は何について不平を言っているのですか? 2 番目のバージョンでは何をしているのでしょうか?

背景情報:ButtonとはどちらもButton.ClickEvent抽象化されていないパブリック クラスです。

4

6 に答える 6

71

内部クラス ( などButton.ClickEvent) には、外部クラス ( Button) のインスタンスへの参照が必要です。

Button.ClickEventこの構文は、外部クラス参照を の値に設定して、の新しいインスタンスを作成しますbutton

以下に例を示します - カプセル化の欠如などは無視してください。これはデモンストレーションの目的のためだけです:

class Outer
{
    String name;

    class Inner
    {
        void sayHi()
        {
            System.out.println("Outer name = " + name);
        }
    }
}

public class Test
{
    public static void main(String[] args)
    {
        Outer outer = new Outer();
        outer.name = "Fred";

        Outer.Inner inner = outer.new Inner();
        inner.sayHi();
    }
}

内部クラスとそれを囲むインスタンスの詳細については、仕様のセクション 8.1.3 を参照してください。

于 2009-03-11T07:02:07.200 に答える
10

Button.ClickEvent は非静的内部クラスであるため、このクラスのインスタンスは Button のインスタンスに囲まれてのみ存在できます。

2 番目のコード例では、Button のインスタンスがあり、この Button インスタンスに含まれる ClickEvent のインスタンスを作成します...

于 2009-03-11T07:00:56.440 に答える
9

Java の非静的内部クラスには、それが宣言されている外部クラスのインスタンスを指す隠し参照が含まれています。そのため、最初に表示されたエラー メッセージは、内部クラスの新しいインスタンスを指定しないと作成できないことを示しています。アタッチする外部クラスのインスタンス。

おそらく、これまでその構文を見たことがないのは、内部クラスが外部クラスのメソッドに割り当てられることが多く、コンパイラがこれを自動的に処理するためです。

于 2009-03-11T07:05:33.603 に答える
3

このめったに使用されない機能で自分自身や他のプログラマーを混乱させないようにするために、常に内部クラスを静的にすることができます。

外部クラスへの参照が必要な場合は、コンストラクターで明示的に渡すことができます。

于 2009-03-11T09:29:24.290 に答える
2

あなたは実際にそれを行うことができますが、内部ClickEventとしてstatic宣言するButton必要があり、sintax を使用しても問題はありません。

buttonClick(new Button.ClickEvent(button));

基本的に、クラスを の特定のインスタンス (つまり)ではなく、staticクラスClickEventに直接所属させます。Buttonnew Button()Button


次の@Jon Skeetの例:

// Button.java
class Button
{

    public static class ClickEvent
    {
        public ClickEvent(Button b)
        {
            System.out.println("Instance: " + this.toString());
        }
    }
}

// Test.java
public class Test
{
    public static void main(String[] args)
    {
        Button button = new Button();
        buttonClick(new Button.ClickEvent(button));
    }

    public static void buttonClick (Button.ClickEvent ce) {
    }
}
于 2016-02-15T14:43:08.350 に答える
-1

入力したコードはコンパイルされます

buttonClick(new Button().ClickEvent(button));

それ以外の

buttonClick(new Button.ClickEvent(button));

コンストラクターはメソッドであるため、Java でメソッドを呼び出すときは、空の場合でも引数のリストを渡す必要があります。

于 2009-03-11T10:20:42.183 に答える