-3

だから私はこの関連コードを持っています...

public class PokemonTrainer {
    private Pokemon p = new Squirtle();
    private String name;

    public PokemonTrainer(String name) {
        this.name = name;
    }

    public static void main(String[] args) {
        PokemonTrainer pt = new PokemonTrainer("Ash");
        try {pt.fightGary();}

        catch (Charmander c) {
            System.out.println("You were roasted by a Charmander.");
        }

        catch (Squirtle s) {
            System.out.println("You were drowned by a Squirtle.");
        }

        catch (Bulbasaur b) {
            System.out.println("You were strangled by a Bulbasaur.");
        }

        catch (Pokemon p) {
            System.out.println("You survived!");
        }
    }

    public void fightGary() throws Pokemon {
        throw p;
    }

public class Pokemon extends Exception {}
public class Bulbasaur extends Pokemon {}
public class Squirtle extends Pokemon {}
public class Charmander extends Pokemon {}

「ゼニガメに溺れた」と表示されるのはなぜですか?

私の推論では、「キャッチ」はメソッドであり、オブジェクトがメソッドに渡されると、メソッドはオブジェクトの STATIC TYPE (この場合は「ポケモン」) に基づいて評価されます。これは以下に示されています。短い例:

public class PokemonTrainer {
    private Pokemon p = new Squirtle();
    private String name;

    public PokemonTrainer(String name) {
        this.name = name;
    }

    public static void main(String[] args) {
        PokemonTrainer pt = new PokemonTrainer("Ash");
        pt.fightGary(pt.p); // ------------ Prints "Pokemon!!!"
    }

    public void fightGary(Pokemon p) {
        System.out.println("Pokemon!!!");
    }

    public void fightGary(Squirtle s) {
        System.out.println("Squirtle!!!");
    }
}

では、これら 2 つの例の違いは何でしょうか。最初の例が何をするかを出力するのはなぜですか?

ありがとう!

4

4 に答える 4

8

私の推論では、「キャッチ」はメソッドです

それが最初の間違いです。catch方法ではないので、それをあたかも方法であるかのように考えようとすると、問題が発生します。

これは、独自のルールを持つ言語構造です。詳細については、言語仕様のセクション 14.20または例外のチュートリアルをお読みください。

つまり、一連のブロックがある場合、スローされた例外の実行時間catchタイプに一致する最初のブロックが実行されます。(コンパイラは、より具体的な例外よりも前に、より一般的な例外をキャッチすることを防ぎます。)

あなたが持っている場合:

try {
  doSomething();
} catch (FileNotFoundException e) {
  ...
} catch (IOException e) {
  ...
}

次に、doSomething()a をスローするFileNotFoundExceptionと、最初のcatchブロック (およびそのブロックのみ) が実行されます。一方、他の種類の をスローすると、2 番目のブロックIOExceptionが実行されます。catch他のすべての例外は、スタックに伝搬されます。

于 2012-08-09T07:34:47.783 に答える
1

は Pokemon として宣言されてPokemon pいますが、 でゼニガメとしてインスタンス化されていますnew Squirtle()。これは内部的にゼニガメであるためgetClass()、呼び出されると Squirtle.class が返されます。したがって、try-catch は、ポケモン キャッチがチェックされる前にゼニガメ キャッチをキャッチします。

これはポリモーフィズムと呼ばれます。

あなたの推論に関してcatchは、メソッドではなく、try特定の例外がスローされた場合に何をすべきかを宣言するブロックに付随するステートメントです。

于 2012-08-09T07:36:35.503 に答える
1

referenceのタイプとのタイプを混同していobjectます。

キャッチはswitchinstanceofオブジェクトの に似ています。

もっと簡単な例を考えてみましょう

String s = "hello";
Object o = s;

この場合、 の参照型はoですObjectが、オブジェクト型はString両方のsでありo、それらは同じオブジェクトであるためです。

于 2012-08-09T07:37:15.277 に答える
1

メソッドでcatchはなく、Java 言語の一部です。

しかし、あなたの質問に答えるにpは、のインスタンスですSquirtle

Pokemon p = new Squirtle();

そして、 acatchをキャッチする句があるため、Squirtleまさにそれを行います。

catch (Squirtle s)

この行が存在しない場合、より一般的な

catch (Pokemon p)

スローされた を処理しSquirtleます。

于 2012-08-09T07:35:40.357 に答える