わかりやすいJavaEEウェブシステム入門でいきなりハマった(macOS Sierra)

p17で最初のプロジェクトを実行したところでデプロイに失敗しハマる
具体的には以下のような状況

以下のページにてmacOS Sierraだとあかんとかなんとか
mac os Sierra でのGlassfish起動

記載の手順に従って、

  1. mac側のシステム環境設定→ネットワーク→詳細→プロキシ→自動プロキシ検出にチェック
  2. NetBeansNetBeans→Preference→「システムのプロキシ設定を使用」の隣にある「再ロード」クリック+その下の「接続のテスト」をクリック で、とりあえず起動できた。

アキネーターの作品版を作ったら金になるのではないかと思った

要件のイメージ(漫画版を仮定)

  • 〜な(抽象的な希望)漫画を探している、といった人がターゲット
  • 漫画喫茶に来たけどいまいち読みたい漫画がない人とか
  • 現実っぽいやつ or ファンタジーっぽいやつ、みたいな選択肢がでてくる
  • 選択肢はだんだん具体的になる(職業モノ or 趣味モノ、とか、人が死ぬかどうか?とか)
  • 最終的に選ばれた作品のAmazonへのリンクが出てきてアフェリエイトで稼ぐイメージ(音楽版だったらYoutubeとか、アフェリエイトあるのか知らんけど)

問題

  • 初期のデータをどう集めるか
  • 初期以降のデータをどう集めるか(どうやって属性とマッチさせていくか、利用者のデータ集めてく感じのような気はする)
  • そもそも選択肢と作品のマッチングをするのがしんどそう。精度が低いと需要ないだろうし

Springのセッターインジェクション

セッターによるインジェクション

@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();

まとめ

  • DIコンテナに格納されたインスタンスは、@AutowiredのついたSetterによってフィールドに値が格納された状態のインスタンスとなる
  • というよりも、DIコンテナにインスタンスが格納されるタイミングで、@Autowiredのついたメソッドが呼び出される、くらいのイメージのがわかりやすいかも
  • その時、Autowiredのついたメソッドの引数は、インジェクションの対象となる
  • メソッドの引数に指定した値のインターフェースがインジェクションの対象にできない(Springの管理下に入っていない)と、起動時にエラーで落ちる

Webサイトを絵画調にするアプリ

昔Webサイトを油絵か何かで正確に模写するアーティスト的なのが出てくるのではと思った

機能イメージ

  • 画面からURLを入力する
  • アプリケーション側で、Selniumか何かでスクショをとる
  • 画像を変換して、油絵っぽくする
  • 画像を返却する
  • twitterか何かで拡散できるようにすると良い
  • ロスコ風とかゴッホ風とか選べたら楽しそう

JSTQB認定テスト技術者資格 Foundation Levelに合格しました

なんで取得したのか

体系的なテストの知識が薄いなと思ったから(お客さんと話していた時にC2カバレッジで〜〜という話がわからなくて困った)

自分の背景

開発の会社に新卒で入社して約3年

やった勉強

感想

  • 教科書を眺めた段階で一週間あればいけるなと思ってたら試験直前の一週間で自分の時間がほとんど取れない誤算があった
  • まとまった時間が取れるのが、試験前日の午前3時からという悲惨な状況
  • ここで教科書丸ごと読むのは一夜漬けでは無理だと判断し、シラバスに絞ったのは賢明な判断だったと思う
  • なんとなく(テスト界隈で)一般的な言葉をある程度網羅的に知れたのは良かったと思うが、シラバスわかりづらいというか、日本語怪しいところあって辛い
  • でもまあある程度体系的に(だいぶざっくりだけど)テストのことを知りたい、という場合には有用なのでは

Effective Javaを読んでいる㉘

例1

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);
    }
}

例2

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);
    }
}

PECS

extendsの基準

メソッド内で入力された型パラメータの変数を使用する場合はextends

なんで?

メソッド内で入力された引数が、型パラメータに指定された型のサブクラスであった場合、親クラスとして使用しても問題ないから

superの基準

呼び出し元に返す(もしくは引数として破壊される対象)のオブジェクトには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はCollection<? super E>の親ではないから?

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{}

なんとなくこんなんでいける気がするけどコンパイルが通らない

Effective Javaを読んでいる㉗

再起型境界

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