「こんにちは、アミーゴ! 数日前、メソッドのオーバーロードについてお話しました。すべて理解できましたか?」
「はい。覚えています。各クラス メソッドは一意である必要があります。クラスに同じ名前とパラメータ タイプを持つメソッドが他にない場合、メンバ メソッドは一意です (パラメータの順序は重要です)。」
「とてもよかったです! レッスンをよく学んだようですね。今日はこのトピックについての知識を少しだけ広げたいと思います。それぞれのケースでどのようなメソッドが呼び出されると思いますか?」
class Cat
{
public static void print(int n)
{
System.out.println(n);
}
public static void print(short n)
{
System.out.println(n);
}
public static void print(Integer n)
{
System.out.println(n);
}
public static void print(String s)
{
System.out.println(s);
}
public static void main(String[] args)
{
Cat.print(1);
Cat.print((byte)1);
Cat.print("1");
Cat.print(null);
}
}
"言うのが難しい。"
「最初のケースでは、 1 は int です。 int を受け取るメソッドと 100% 一致します。最初のvoid print(int n)が呼び出されます。
2 番目のケースでは、バイトを受け取るメソッドがありません。ただし、short と int を受け取るメソッドが 2 つあります。型拡張ルールに基づいて、バイトはまず short に拡張され、次に int に拡張されます。したがって、判定はvoid print(short n) になります。呼ばれます。
3 番目のケースでは、文字列を受け取るメソッドと 100% 一致します。void print(String s)。メソッドが呼び出されます。
4番目のケースは曖昧です。null には特定の型がありません。コンパイラはこのコードのコンパイルを拒否します。この場合、3 番目のメソッドを呼び出すにはCat.print((Integer)null)を記述し、4 番目のメソッドを呼び出すにはCat.print((String)null) を記述する必要があります。」
「とても勉強になりました。ありがとうございました。」
「呼び出す正しいメソッドを決定するとき、型は拡大することしかできず、縮小することはできないことを指摘したいと思います。次の例を考えてみましょう。」
class Cat
{
public static void print(short n)
{
System.out.println(n);
}
public static void print(Integer n)
{
System.out.println(n);
}
public static void main(String[] args)
{
Cat.print((byte)1);
Cat.print(1);
}
}
最初のケースでは、バイト型が short に拡張され、最初のメソッド void print(short n) が呼び出されます。。
2 番目のケースでは、int から Integer への暗黙的な拡大変換が行われ、その後 2 番目のメソッドvoid print(Integer n)が呼び出されます。。
「そんなことは期待していなかった。」
「いいえ、本当の驚きはここにあります。」
Javaコード | 説明 |
---|---|
|
最初のケースでは、int は Integer に拡張されます。Integer のメソッドがないため、最も適切なメソッド (および呼び出されるメソッド) はvoid print(Object o)です。
2 番目のケースでは、コンパイル エラーは発生せず、void print(String s) が呼び出されますが、これはやや明らかではありません。 |
「アミーゴ、このような場合、どのメソッドが呼び出されるのかを正確に知るためには、(«(byte)» で行ったように) 型キャスト演算子を指定するのが最善であることを理解していただければ幸いです。」
「メソッドのオーバーロードによって問題が発生するとは予想していませんでした。しかし、あなたがやって来ました。ありがとう、リシ。私はこの点については気をつけます。」
GO TO FULL VERSION