yuki8634
@yuki8634 (yuki kawakita)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Java Gold コンパイルエラーと実行時エラーについての疑問

解決したいこと

Java Goldの黒本を解いていた時に疑問に思っていたことを解決したいです。

該当する問題

  1. (Java Gold黒本第13章8問目参照)
    次のプログラムをコンパイル、実行した時の結果として、正しいものを選びなさい
public interface Test{
    public default void execute(String str){
        System.out.println("A");
    }
}

public abstract class AbstractTest{
    private void execute(String str){
        System.out.println("B");
    }
}

public class Sample extends AbstractTest implements Test{
    public static void main(String[] args){
        new Sample().execute("hello");
    }
}

A.「A」と表示される
B.「B」と表示される
C.コンパイルエラーが発生する
D.実行時に例外が発生する

正解:D
クラスに定義しているメソッドが優先されるというルールはコンパイル時に適用されるため、コンパイラはインターフェースに定義されているpublicなexecuteメソッドを実行するものと解釈し、コンパイルは成功します。しかし、実行時には前述のルールが適用されるため、不正なアクセスをしたことを示す例外IkkegalAccessErrorがスローされます。

2.(Java Gold黒本第1章13問目参照)
次のプログラムをコンパイル、実行した時の結果として正しいものを選びなさい

public interface A{
    public default void test(){
        System.out.println("A");
    }
}

public abstract class B{
    protected void test(){
        System.out.println("B");
    }
}

public class Sample extends B implements A{
    public static void main(String[] args){
        new Sample().test();
    }
}

A.「A」と表示される
B.「B」と表示される
C.コンパイルエラーが発生する
D.実行時に例外が発生する

正解:C
Sampleクラスが実現しているAインターフェースと継承しているBクラスが、同じシグニチャのメソッドを持っています。コンパイラは、SampleクラスはBクラスを引き継いだ上でAインターフェースを実現していると解釈されます。
Bクラスから引き継いだtestメソッドが、Aインターフェースに定義されているtestメソッドと互換性がないと判断されるため、コンパイラエラーが発生します。

分からないこと

二つのコードを見比べるととても似ていますが、片方はコンパイルエラー、片方は例外をスローと違う結果になります。
二つのコードの相違点といえば、abstractクラスのメソッドがprivateかabstractかどうかや、メソッドの引数がないかどうかくらいです。

今自分の中の仮説では、privateなメソッドはコンパイラが検知できないため、コンパイル自体は成功するが実行時に例外がスローされる。と言うものです。
テキストの解説には特にそのような説明はありませんでしたので、確実ではありません。

なぜそうなっているのか、原理原則を踏まえてご教授願います。

1

No Answers yet.

Your answer might help someone💌