Java学習 List型でArrayListやLinkedListを宣言する理由を推察(間違いあり)
※未経験エンジニアが語る戯言を含みます。
たぶんソースを私が読める限り読んだ感じではこういうことだと思います。
Listがインスタンス化できないのはインターフェースだから当然として、途中にAbstractListという具象メソッドも提供できる抽象クラスが入っているのがミソです。
AbstractListにはaddやremoveなど、List型に共通のメソッドが定義されています。
ArrayListやLinkedListのソースが現役エンジニアの方でも苦戦する程度には難しいらしいので、推測も含みますが、おそらくオーバーライドされない限り、つまりAbstractListで定義されたList型共通のメソッドを使っている状態。つまりつまり、この辺を再度確認しましたが、実装によって違うそうです。
List<T> list = と宣言されているなら右辺がArrayListだろうとLinkedListであろうとそれらの特徴は無視されている・・・はず。
ソースが読み切れないので、実験的に色々確認した結果が以下になります。
あくまで型情報を共通にしているだけみたいです。
左辺をList<T> list = で宣言する大きなメリットとしては、
List<T>型で宣言しておけば、ArrayListにもLinkedListにも互換性を持てるのです。
しかしArrayListやLinkedListで宣言してしまうと、List型で宣言した変数と互換性がありません。
今後、どのように使われるかわからないので、拡張性を持っておくために、左辺をList<T>型で宣言している。
左辺がサブクラス型にならない限り、その個性はたぶん表れません。
表れてしまったら、List<T> listにArrayListの特徴、LinkedListの特徴、その他の特徴を持ったlistが作れてしまいます。
この辺はメソッドの実装方式によって現れるようです。
ソースをきちんと読めるようになったら確認してみたいですね~
下のコードのコメントは誤りですが、思考の履歴を辿りたい時のために残しておきます。
import java.util.List;
import java.util.ArrayList;
import java.util.LinkedList;
public class Main {
public static void main(String[] args) {
//宣言がListならArrayListとLinkedListが互換性があること
//を確認するために宣言
List<Integer> number = new ArrayList<>();
List<Integer> number2 = new LinkedList<>();
//型に互換性がないことを確認するために宣言
LinkedList<Integer> number3 = new LinkedList<>();
ArrayList<Integer> number4 = new ArrayList<>();
//List<Integer> number = new ArrayList<>();に数を代入
for(int i = 1 ; i < 11 ; i++) {
number.add(i);
}
//List<Integer> number2 = new LinkedList<>();に数を代入
for(int i = 11 ; i < 21 ; i++) {
number2.add(i);
}
//numberとnumber2には「互換性がある」ので追加できる。
//もしArrayListやLinkedListの特徴が出ているなら追加できない(はず)
//AL型やLL型の特徴(アクセスの優位性の差など)が出るとしたら
//numberにはList型、AL型、LL型の3種類の型がある(おかしい)
number.addAll(number2);
for(int i : number) {
System.out.println(i);
}
//List型にはLinkedList型も入れられる。
//ArrayList型なども同様
number = number3;
//逆にArrayList型などのサブクラスで宣言すると
//ダウンキャストしても実行時にClassCastExceptionが起こる
number4 = (ArrayList<Integer>) number2;
for(int i : number) {
System.out.println(i);
}
}
}
この記事が気に入ったらサポートをしてみませんか?