LoginSignup
2
1

More than 5 years have passed since last update.

Javaの仕様メモ

Last updated at Posted at 2019-01-22

あまり他人に読ませるつもりでまとめていない、自分用メモ。

Primitive Type

  • 数値型にunsignedはない
  • NaNや +0.0 と -0.0 の比較のため、浮動小数点は == じゃなくて Double.compare を使う

継承

継承の例:

interface Foo {
    void bar();
}

class Foo extends Bar implements Foo {
    ...
}

複数継承

  • C++と違ってクラスの複数継承はできない

演算子

  • C++と違ってoperator overloadingはできない

equalsのオーバーライド

  • 以下の規則を満たすように実装する:
    • 反射的 (reflexive): x.equals(x) は true
    • 対称的 (symmetric): y.equals(x) が true の場合のみ、x.equals(y) も true
    • 推移的 (transitive): x.equals(y) 、y.equals(z) が true ならば、x.equals(z) も true
    • 整合的 (consistent): 情報が変更されなければ、x.equals(y) の結果は不変
  • hashCodeもオーバーライドする

final, finally, finalize

final

  • クラス: 継承できる
  • メソッド: オーバーライドできない
  • 変数: 変更できない

finally

  • return, continue, breakや例外など、通常は何をやってもfinallyは実行される
    • スレッドやVMが突然死んだ場合は実行されない
    • System#exit や Runtime#exit でも実行されない

finalize

  • JVMがオブジェクトをGCする前に走らせるメソッド
  • Java 9でdeprecatedなので覚えておく必要はない

修飾子

abstract

  • クラス: abstractメソッドを持つ。instantiateできない。
  • インターフェース: 全てのinterfaceは非明示的にabstractになっているので、abstractは書かなくてもよい
  • メソッド: 定義を持たないメソッド。クラスもabstractでないといけない。

protected

  • メソッド、変数にのみ付与可能
  • 同一クラス、サブクラスから参照できる

private

  • コンストラクタをprivateにするとそのクラス外でクラスをinstantiateできなくなる。
    • Factory Method パターンでstatic publicメソッドからのみ作るのに使われる。
    • 継承は不可能になる

static

  • メソッド: クラスメソッドになる
  • 変数: クラス変数になる。クラスに1つになり、クラス名からアクセス可能

volatile

  • マルチスレッド環境のため、スレッド間のフィールド値のキャッシュを防ぎ、また代入処理などのreoderを防ぐ
  • 更新に依存関係がある場合などはvolatileは不十分で、synchronizedブロックを使わなければいけない

クラス

外部クラス

  • 内部クラスを持つクラスのこと
  • 外部クラスにはstaticは存在しない
  • 外部クラスにはprivateも書けない
    • デフォルトでは同パッケージ内からのみアクセス可能、publicにすると別パッケージから使える
    • publicなクラスはファイル名も揃える必要がある

内部クラス

  • 外部クラスにネストして定義するクラス。外部クラスでないクラスからでも使える
  • 外部クラスのオブジェクトから内部クラスをinstantiateすると、外部クラスのメンバにアクセスできる
  • 非static 内部クラスはstaticなコンテキストからinstantiateできない

ローカルクラス

  • 外部クラスのメソッド内で定義したクラス
  • 内部クラスの一種なので、staticなフィールドやメソッドは作れない

static 内部クラス

  • 内部クラスと全く挙動が異なる
  • 外部クラスのオブジェクトからではなく、外部クラスからinstantiateする
  • 当然外部クラスの非staticなメンバにアクセスできない。staticならアクセスできる

String

  • ==: Stringは == で比較してはいけない
  • +: Javaの文字列連結は内部的にStringBuilderを使うので、+でStringを連結しまくると遅い
  • length(): Unicodeコード単位の数を返すだけなので、サロゲートペアを含むで期待通り動作しない。codePointCountを使う
  • String#split はPatternではなくStringとして正規表現を取る

Integer

  • コンストラクタではなく Integer.valueOf(int) などのファクトリメソッドを利用するようにする。インスタンスが使い回されるかもしれないため。

Deque

Double-ended queue。Queue interfaceを実装しているのでQueueとして使えるが、Stackはclassなので実装していない。
一方、StackよりもDequeを使うようにStackのドキュメントで推奨されているので、Stack風のinterfaceが要る時はDequeを使うべきである。StackはVectorを実装しており、本来不要そうなインデックスアクセスができる。

一般に、LinkedListは全操作が$O(1)$で、ArrayDequeのような実装だと追加の最悪計算時間が$O(n)$になるものの、全ての操作のTime ComplexityはAmortized Analysisで$O(1)$になる。

ヒープの連続領域を確保するクラス

  • ByteArrayOutputStream
  • Buffered* (BufferedInputStream)
  • ArrayList
  • String
  • StringBuilder

メモリの使いすぎに注意

レガシークラス

  • Vector => ArrayList
  • Stack => LinkedList
  • HashMap => Hashtable
  • StringBuffer => StringBuffer

比較

任意クラスの比較を実装する方法は主に2つある。

Comparable.compareTo

class Foo implements Comparable<Foo> {
    int key;

    public Foo(int key) { 
        this.key = key;
    }

    @Override
    public int compareTo(Foo f){
        return this.key - f.key;
    }
}

Collections.sort(fooList);
Collections.sort(fooList, Collections.reverseOrder());

Comparator.compare

class FooComparator implements Comparator<Foo> {
    @Override
    public int compare(Foo a, Foo b) {
        return a.key - b.key;
    }
}

Collections.sort(fooList, new FooComparator());

スレッド

使い方の例

class Foo implements Runnable {
    public void run() {
        while (true) System.out.print(".");
    }
}

Foo foo = new Foo();
Thread thread = new Thread(foo);
thread.start();

スレッドセーフではないクラス

  • SimpleDateFormat
  • ...

並行にアクセスがある際 synchronized などで扱う必要がある

参照

参照には以下の種類がある:

  • Strong: 普通の参照
  • Weak: String referenceがなくなるとGCされる参照
  • Soft: Weakと違い必ず消えるとは限らず、本当にメモリが必要な場合のみ消される。GCはOutOfMemoryErrorになる前にこれはクリーンアップする必要がある
  • Phantom: finalizeを自分でスケジューリングするために使う https://qiita.com/yoshi389111/items/66448f9a013eee4be035

Generics

  • クラスもメソッドもジェネリックにできる
  • Primitive Typeはパラメータにできない
  • ? super Xxx? extends Xxx を書いて bounded type parameter を定義できる
  • Parameter Typeはinstantiateできない
  • staticなメソッドや変数にParameter Typeを利用できない

その他後で調べたいもの

  • object reflection: Class.forName など
  • class loader
  • dependency injection
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1