あまり他人に読ませるつもりでまとめていない、自分用メモ。
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