3

私は専門的に書かれたコードを調べていて、このフラグメントに出くわしました。(この断片が私の質問に答えるのに十分であることを願っています-そうでない場合はお知らせください)

...yada yada yada ....

private ITypedElement format(final ITypedElement elementToFormat) {
        try {
            if (elementToFormat instanceof IStreamContentAccessor) {
                final IStreamContentAccessor resNode = (IStreamContentAccessor) elementToFormat;
                final InputStream contentIs = resNode.getContents();
                final String contentsString = fromInputStreamToString(contentIs);
                final Map options = JavaCore.getOptions();
.... etc....

ifセグメントelementToFormatは、 が のインスタンスである場合にのみ実行されますIStreamContentAccessor。では、なぜプログラムはifステートメント "の後に最初のステートメントを作成したのfinal IStreamContentAccessor resNode = (IStreamContentAccessor)elementToFormat;"ですか?

何かをすでにあるはずの型にキャストするポイントは何でしょうか?

4

5 に答える 5

5

プログラマーはそれが であることを知っているかもしれIStreamContentAccessorませんが、キャストがなければコンパイラーはそれが であることを認識していないため、プログラマーはクラスIStreamContentAccessorに固有のフィールド/メソッドにアクセスできません。IStreamContentAccessor

class ClassA {
    Object field1;
}

class ClassB extends ClassA
    Object field2;
}

ClassA obj = new ClassB();
obj.field1;  // This is fine, the compiler knows it's a ClassA
obj.field2;  // This isn't allowed - as far as the compiler knows it's a ClassA, not a ClassB
((ClassB)obj).field2;  // This is allowed - now the compiler knows it's a ClassB
于 2013-05-08T20:27:34.657 に答える
3

このifステートメントは、オブジェクトがその型のインスタンスであることを保証します。ただし、JVM にとっては、オブジェクトはまだタイプITypedElementです。有効であることわかったからといって、JVM がそれを知っているとは限りません。

キャストにより、 のメソッドにアクセスできますIStreamContentAccessor。キャストなしで、持っていないが持っているelementToFormatメソッドで参照すると、エラーが発生することに気付くでしょう。ITypedElementIStreamContentAccessor

例えば:

Animal a;
a = new Dog();
// "a" contains a Dog in memory, but we only KNOW that it's an Animal
// because that is its declared type

a.bark(); // fails at compile time - not all Animals can bark

Dog d = (Dog) a;
// This is a valid cast, because Dog extends Animal, but it's potentially unsafe.
//
// Another "valid" cast is:
// Cat c = (Cat) a
// but this would fail at runtime (ClassCastException) because the actual
// object in memory (a Dog) cannot be cast to a Cat.

if (a instanceof Dog) {
    // Now we KNOW that it's a Dog and we can cast safely.
    Dog d2 = (Dog) a;
    d2.bark(); // this is valid because d2's declared type is Dog
}

要約すると、

  • キャストにより、サブクラスのフィールドへのアクセスが許可されます
  • このifステートメントは、キャストが有効であることを保証します
  • 2 つのステートメントは技術的に完全に独立しています。
  • あなたはJREより頭がいい
于 2013-05-08T20:27:54.710 に答える
1

これは煩わしいですが、Java 言語で必要です。

変数 elementToFormat は ITypedElement 型です。IStreamContentAccessor として使用するには、キャストが必要です。

この特定のケースでは、ローカル パラメーターはキャスト型でなければならないことがわかります。ただし、代入の右側は、メンバー変数や関数呼び出しなど、ローカル パラメーター以外のものである可能性があります。右側の値がどこから来ているかに関係なく、同じ型チェック規則が一貫して右側の値に適用されます。

タイプを 3 回繰り返さなければならないため、このイディオムは煩わしいものです。これは、私たちにとって少し余分な作業を意味します。しかし、ダウンキャストはコードのにおいがする場合があるため、このイディオムはちょっとした構文上のソルトと考えることができます。

于 2013-05-08T20:28:02.527 に答える
0

これは型ではないfinal IStreamContentAccessor resNode = (IStreamContentAccessor) elementToFormat;ため述べられていますが、安全にキャストできます。elementToFormatIStreamContentAccessor

于 2013-05-08T20:27:56.480 に答える