ジェネリック型パラメーターを持つメソッドと非ジェネリックパラメーターを持つメソッドがある場合、Javaはどのオーバーロードされたメソッドを呼び出すかをどのように決定しますか?

Md。KawserHabib

Javaクラスは、型消去後に同じシグネチャを持つ2つのオーバーロードされたメソッドを持つことはできません。Javaは、以下のシナリオでコンパイル時エラーを生成します。

public class Example {
    public void print(Set<String> strSet) { }
    public void print(Set<Integer> intSet) { }
}

しかし、私の質問はそれではありません。シナリオ1と2が2つあります。知りたいのですが、なぜそれらの動作が同じではないのですか?

Scenario 1

import java.util.ArrayList;
import java.util.List;

public class MethodOverload {

    public static void main(String[] args) {
        
        MethodOverload methodOverload = new MethodOverload();

        //Point 1 - List here
        List<Integer> mangoList = new ArrayList<Integer>();
        mangoList.add(1);
        mangoList.add(2);
        
        System.out.println("Size List<Integer>:"+methodOverload.count(mangoList));
        
        //Point 2 - ArrayList here
        ArrayList<String> nameList = new ArrayList<String>();
        nameList.add("Anex");
        nameList.add("Alia");
        nameList.add("Maxim");
        
        System.out.println("Size List<String>:"+methodOverload.count(nameList));
    }
    
    public <T> int count(List<T> list) {
        System.out.print("Ïn side generic; ");
        return list.size();
    }
}

シナリオ1の出力

Inside generic block; Size List<Integer> : 2
Inside generic block; Size List<String>  : 3

Scenario 2:

import java.util.ArrayList;
import java.util.List;

public class MethodOverload {

    public static void main(String[] args) {
        
        MethodOverload methodOverload = new MethodOverload();

        //Point 3 - List here
        List<Integer> mangoList = new ArrayList<Integer>();
        mangoList.add(1);
        mangoList.add(2);
        
        System.out.println("Size List<Integer>:"+methodOverload.count(mangoList));
        
        //Point 4 - ArrayList here
        ArrayList<String> nameList = new ArrayList<String>();
        nameList.add("Anex");
        nameList.add("Alia");
        nameList.add("Maxim");
        
        System.out.println("Size List<String>:"+methodOverload.count(nameList));
    }
    
    public <T> int count(List<T> list) {
        System.out.print("Inside generic block; ");
        return list.size();
    }
    
    //Point 5
    public int count(ArrayList<String> list) {
        System.out.print("Inside non-generic block; ");
        return list.size();
    }

}

シナリオ2の出力。

Inside generic block;     Size List<Integer> : 2
Inside non-generic block; Size List<String>  : 3

さて、私の質問は、Javaがどのメソッドを呼び出すかをどのように決定するのscenario 2かということです。ではscenario 1Javaはどんな問題なく、単一のカウント法と呼ばれるところ、なぜJava用の同様の挙動を示していませんかscenario 2

コーネルマッソン

型消去はジェネリック型にのみ適用されるためです。Javaは継承を「消去」しません。

シナリオ1では、count()メソッドのシグネチャは実行時に事実上次のようになります。

public Object int count(List<Object> list) {...}

したがって、mangoList(リストとして宣言)とnameList(ArrayListとして宣言)の両方がこの署名に適合します。

シナリオ2では、メソッドシグネチャは実行時に事実上次のようになります。

public Object int count(List<Object> list) {...}

public int count(ArrayList<Object> list) {...}
  • mangoListはリストとして宣言されているため、Javaはリストを引数として最初のcount()メソッドに適合させます。
  • nameListはArrayListとして宣言されているため、JavaはArrayListを引数として、それを2番目のcount()メソッドに適合させます。

Javaは、ジェネリックスが登場するずっと前に、この(継承ベースの)オーバーロードを行う方法を知っています。実行時の型消去のために、バインドされていないジェネリック型に基づいてオーバーロードすることはできません。そのため、コンパイラーはそれを停止します。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ