読者です 読者をやめる 読者になる 読者になる

Effective Javaを読んでいる㉘

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

これが通らないのは何故だろう

Effective Javaを読んでいる㉗

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

Effective Javaを読んでいる㉖

Java

ジェネリクスを使おう

具象不可能型は配列を生成できない

DelayQueueってなに
→Delayedインターフェースを実装したクラスのみ格納できるキュー
→Delayedインターフェースを実装したクラスがオーバーライドしたgetDelayedメソッドの戻り値が0未満でないと、要素を取得できない
タイムアウトを設定して待機したりできる
APIを非同期で何回もよんで呼び出しと結果を管理するオブジェクトを突っ込んで云々みたいな?いまいちイメージがわかない
DelayQueue (Java Platform SE 7)

スカラー型への無検査キャストを抑制するよりは配列型への無検査キャストを抑制する方が、危険性は高いです。とは? java - What is a Scalar type and why is it riskier to suppress an unchecked cast to an array type than to a scalar type? - Stack Overflow ・EはObjectのサブクラスではない(EはObjectのサブクラスであるという話?)
・配列のキャストではコードが型安全かどうか保証するのが複雑になるから
いまいち理由としてはピンとこないけど↓の2人目の人が書いているサンプルコードはわかりやすい
配列自体が絶対に外から見えないようにするなら配列をキャストした方が安全な気はするけど http://stackoverflow.com/questions/14986765/what-is-a-scalar-type-and-why-is-it-riskier-to-suppress-an-unchecked-cast-to-an

まとめると以下のイメージ?
・Object型から総称型への配列のキャストは許可されている
・が、型そのものはObject型のままである
・外側から見た時、総称型のクラスを使用する際に、型変数には具体的な型を使用する
・総称型へキャストされた配列をクライアントが使用するとき、クライアントではその配列は「型引数に指定した配列」として使う(使いたくなる)。
・が、実態はObject型の配列であり、特定の型の配列に格納するとClassCastExceptionがスローされる

キャストについて − Java Solution − @IT

Youtubeうんちままごとの世界

その他

Youtubeで何の気なしに「うんち」で検索したら児童向けの玩具でおままごとをしてる動画がたくさんでてきました。

いくつか見てみたんですが、すごいです。そのへんのちょっとおかしい人のブログとか、アナーキーなことをするYoutuberを軽く超えています。 とにかくひとつ見ていただきたい。

www.youtube.com
バタコさんが野外でうんちをして、それから一回出したうんちを戻すストップモーションアニメです。 うんちを戻す・・・?

www.youtube.com
次はバタコさんがうんちを販売しているアニメです。 うんちを購入していくメロンパンナちゃんやジャムおじさんを見たバイキンマンが、「みんなあたまおかしい」と呟いています。

いくつかの動画を見ていて、私は気が付きました。作者が一人ではないと。
最初はこう、なんといいますか、ぷりんてぃんとか、魔ゼルな規犬とか、そういったちょっとアバンギャルドなアーティスト的な活動をしている方かな、と思っていたんですが、どうやらこれは個人による活動ではなく、一つのムーブメントのようです。

人は自分の目の前に自分知らない世界が広がっていた時、その世界が広ければ広いほど、不安と好奇心の混じった気持ちになります。歳をとればとるほどこの不安は大きくなり、知らない世界を受け入れがたくなるようです。理解できないものを、「理解できないから駄目だ」で片付けず、好奇心をもって接していく気持ちを忘れずに、今年も暮らしていきたいと思いました。

4コマ漫画を生産するためのアプリ

その他
  • 各コマの画像を選ぶ
  • エディタで吹き出しの配置とセリフの設定ができる →ここ
  • 投稿できる
  • 自分で画像をアップロードして使うことも出来る
  • アップロードした画像は他の人も使える
  • 投票できる

ホームページレッカー

その他

クライアントサーバ

クライアント:URLを入力してリクエスト
サーバ:受け取ったURLへアクセスしページを取得
   :ページ内のURL(cssとか画像とか)を文字列変換で絶対パスに治す→ページはURLのものを表示したいけどドメインが変わるので※1
サーバ:DOMをランダムにぐちゃぐちゃにする(どうやる?いわゆるHTMLパーサーでできる?)※2
サーバ:ぐちゃぐちゃにしたページをクライアントに返却

・普通に考えるとXSSし放題なのでどうしようかな
・※1は対象絞ればふつうにテキスト置換でいいような
・※2は真面目に考えたいけどそもそも何でコントロールするのがいいのかな
・本当はスクショとってtwitterでシェアまでしたい気持ち

homepage wrecker

入力ページへのリクエストを送信したIPと実際にデータを送信したIPが違っていたらエラーにしたい

その他

https://www.websequencediagrams.com/cgi-bin/cdraw?lz=dGl0bGUgcmVxdWVzdCBmcm9tIHNhbWUgaXAgCgpVQS0-YXBwOgAYBwphcHAtPnNlc3Npb246aXAKAAQHAB8GABgGVUE6aW5wdXQgZm9ybQA4CVVSTAAvDgA-ByBpZAA3DmlwAF8GYXBwOmNoZWNrAIEGCApub3RlIHJpZ2h0IG9mIGFwcDogSWYgYWNjZXB0ZWQgaXAgaXMgbm90AIE2CWluIACBJAcsIHJldHVybiBlcnJvciBwYWdlLgCBJQkAFAdicmVhayB3ZWIgc2l0ZQCCAwZVUkwK&s=napkin

かんがえちゅう

title request from same ip

UA->app:request app->session:ip session->app: app->UA:input form UA->app:URL app->session:session id session->app:ip app->app:check same ip note right of app: If accepted ip is not same ip in session, return error page. app->UA:return break web site from URL