p17で最初のプロジェクトを実行したところでデプロイに失敗しハマる
具体的には以下のような状況
- glassfishは起動可能(ブラウザからlocalhost:8080でアクセスできる)
- が、NetBeans上からglassfishを停止できない(停止ボタンがグレーアウトしている)
- NetBeansを終了してもglassfishのプロセスが残る
以下のページにてmacOS Sierraだとあかんとかなんとか
mac os Sierra でのGlassfish起動
記載の手順に従って、
@Component public class SetterInjectionServiceImpl implements SetterInjectionService{ //インジェクション対象 private Test target; //セッターによるインジェクション @Autowired private void setTarget(Test target){ this.target = target; } @Override public void show(){ System.out.println("セッターインジェクションにてインジェクションされたインスタンス:" + target); } }
//このsetterにはすでにtargetが格納されている SetterInjectionService setter = context.getBean(SetterInjectionService.class); setter.show();
体系的なテストの知識が薄いなと思ったから(お客さんと話していた時にC2カバレッジで〜〜という話がわからなくて困った)
開発の会社に新卒で入社して約3年
教科書を眺めた(30分くらい) www.amazon.co.jp
模擬試験のアプリ(5時間くらい) play.google.com
シラバスを全部読んだ(10時間くらい)
JSTQB認定テスト技術者資格-シラバス(学習事項)・用語集-
import java.util.ArrayList; import java.util.List; public class Test { public static void main(String[] args) { List2<Object> list = new List2<>(); List<String> sList = new ArrayList<>(); List<Object> oList = new ArrayList<>(); //List<String>はList<Object>のサブクラスではないので以下の呼び出しはコンパイルエラー list.merge(oList, sList); } } class List2<E> extends ArrayList<E> { public void merge(List<E> l1, List<E> l2){ this.addAll(l1); this.addAll(l2); } }
import java.util.ArrayList; import java.util.List; public class Test { public static void main(String[] args) { List2<Object> list = new List2<>(); List<String> sList = new ArrayList<>(); List<Object> oList = new ArrayList<>(); //List<? extends E>の型パラメータはEのサブクラスであるため以下は許容される list.merge(oList, sList); } } class List2<E> extends ArrayList<E> { public void merge(List<E> l1, List<? extends E> l2){ this.addAll(l1); this.addAll(l2); } }
import java.util.ArrayList; import java.util.Collection; public class Test { public static void main(String[] args) { List2<String> list = new List2<>(); //ArrayList<Object>はCollection<String>の親クラスではない list.merge(new ArrayList<Object>()); } } class List2<E> extends ArrayList<E> { /** * 引数のコレクションに要素を全て追加 */ public void merge(Collection<E> collection){ collection.addAll(this); } }
import java.util.ArrayList; import java.util.Collection; public class Test { public static void main(String[] args) { List2<String> list = new List2<>(); //ObjectはStringの親クラスであるため以下は許容される list.merge(new ArrayList<Object>()); } } class List2<E> extends ArrayList<E> { /** * 引数のコレクションに要素を全て追加 */ public void merge(Collection<? super E> collection){ collection.addAll(this); } }
メソッド内で入力された型パラメータの変数を使用する場合はextends
メソッド内で入力された引数が、型パラメータに指定された型のサブクラスであった場合、親クラスとして使用しても問題ないから
呼び出し元に返す(もしくは引数として破壊される対象)のオブジェクトにはsuper
呼び出し元で型パラメータ化した変数にとって、その型パラメータのサブクラスを型パラメータ化した型として扱っても問題ないから
全ての子クラスは親クラスとしても使えなければならない(リスコフの置換原則)
import java.util.ArrayList; import java.util.Collection; public class Test { public static void main(String[] args) { ExtendsList<Child> list = new ExtendsList<>(); //これが許容されないのは何故だろう Collection<Object> objs = list.merge(new ArrayList<Child>()); } } class ExtendsList<E> extends ArrayList<E> { // 戻り値はEの親のコレクションとして使いたい 引数はEの子のコレクションとして使いたい public Collection<? super E> merge(Collection<? extends E> collection){ this.addAll(collection); return this; } } class Child extends Object{ } class ChildChild extends Child{ }
これが通らないのは何故だろう
Collection
import java.util.ArrayList; import java.util.Collection; import java.util.List; public class Test { public static void main(String[] args) { ExtendsList<Child, Object> list = new ExtendsList<>(); Collection<Object> objs = list.merge(new ArrayList<Child>()); } } class ExtendsList<E extends T, T> extends ArrayList<E> { public Collection<T> merge(Collection<E> collection){ List<T> list = new ArrayList<>(); list.addAll(collection); return list; } } class Child extends Object{}
こんな感じにしたい場合は? ExtendedListの型パラメータにObjectを指定しないでこれをできてもいいような
こんなん?
import java.util.ArrayList; import java.util.Collection; import java.util.List; public class Test { public static void main(String[] args) { ExtendsList<Object> list = new ExtendsList<>(); Collection<Object> objs = list.merge(new ArrayList<Child>()); } } class ExtendsList<T> extends ArrayList<T> { public Collection<T> merge(Collection<? extends T> collection){ List<T> list = new ArrayList<>(); list.addAll(collection); return list; } } class Child extends Object{}
ExtendsListのインスタンスを最初からChildで宣言するのは無理なのかな
import java.util.ArrayList; import java.util.Collection; import java.util.List; public class Test { public static void main(String[] args) { ExtendsList<Child> list = new ExtendsList<>(); Collection<Parent> objs = list.<Parent>merge(new ArrayList<Child>()); } } class ExtendsList<T> extends ArrayList<T> { public <E super T> Collection<E> merge(Collection<? extends E> collection){ List<E> list = new ArrayList<>(); list.addAll(collection); return list; } } class Parent{} class Child extends Parent{}
なんとなくこんなんでいける気がするけどコンパイルが通らない
再起型境界
import java.util.List; public class Test { //引数がCompareble2<T>型のリストであることが保証されるためOK private static <T> Comparable2<T> max1(List<Comparable2<T>> list){ Comparable2<T> max = list.get(0); for(Comparable2<T> t : list){ if(max.compareTo(t) > 0){ max = t; } } return max; } //TはCompareble<T>を継承していることが保証されるためOK private static <T extends Comparable<T>> T max2(List<T> list){ T max = list.get(0); for(T t : list){ if(max.compareTo(t) > 0){ max = t; } } return max; } //これはだめ private static <T> Comparable<T> max3(List<Comparable<T>> list){ Comparable<T> max = list.get(0); for(Comparable<T> t : list){ //Compareble<T>のcompareToの引数はT型であり、Compareble<T>型ではないため不可!! if(max.compareTo(t) > 0){ max = t; } } return max; } } interface Comparable2<T>{ /** 引数のがおおきかったら正、小さかったら負、同じだったら0を返す */ int compareTo(Comparable2<T> t); //Comparebleではメソッドの範囲でTがComparableを実装していることを保証していない // int compareTo(T t); }
読んでおきたい d.hatena.ne.jp