Open14

01.INBOX

Takayuki ShojiTakayuki Shoji

static

staticとは「静的」を意味する。

staticフィールド

staticフィールドはインスタンスをどれだけ生成したとしても、クラスにたった一つ。
複数のインスタンス間で共有され続ける情報、共有資源にしたいフィールドにstaticをつける。
よって、staticフィールドを呼ぶ場合はクラス名.フィールド名で呼ぶ。インスタンスを生成して呼び出しても同じものにアクセスできる。
定数を定義する際はfinal staticで宣言することで、newするたびに同じ値がインスタンスに複製されることを防ぎ、メモリ節約に役立つ。

public final static String KEY = "test";

どこから呼び出しても固定値testになるKEY

staticメソッド(クラスメソッド)

staticメソッドは、そのものがクラスのインスタンスではなく、クラスに属する。
呼び出しはクラス名.メソッド名、関数型インターフェースのメソッド呼び出しの場合はクラス名::メソッド名で直接呼び出しができる。
staticフィールドとstaticメソッドは、静的メンバと呼ばれる。
staticがつかない一般のメソッドは非staticメソッド、インスタンスメソッドと呼ぶ。

public class MethodReference {
  
  public static void main(String[] args) {
    // staticメソッド(関数型インターフェース)
    wakeUp(MethodReference::printWakeUp);

    System.out.print(" and ");

    // インスタンスメソッドの生成
    MethodReference methodReference = new MethodReference();
    methodReference.goToilet(methodReference::printGoToilet)

  }

  interface Human {
    void doSomething();
  }

  static void wakeUp(Human human) {
    human.doSomething();
  }

  static void printWakeUp() {
    String wakeUp = "wake up";
    System.out.print(wakeUp);
  }

  void goToilet(Human human) {
    human.doSomething();
  }

  void printGoToilet() {
    String toilet = "happy toilet";
    System.out.print(toilet);
  }
}

結果はwake up and happy toilet
  
オーバーライドはできない

public class StaticPractice {

  public static void main(String[] args) {

    // HumanクラスのdeveloperインスタンスをDeveloperクラスで生成しようとしている
    Human developer = new Developer();

    System.out.println(developer.getMorning());

    // 上記のようにインスタンスをわざわざつくらなくてもクラスメソッドを直接使うことができる
    System.out.println(Human.getMorning());
  }
}

class Human {
  static String morning = "Happy Toilet";

  static String getMorning() {
    return morning;
  }
}

class Developer extends Human {
  static String morning = "Happy Coding";

  static String getMorning() {
    return morning;
  }
}

結果はHappy Toilet

public static void main(String [] args)

メインメソッドが呼び出される時、まだメモリにインスタンスは存在していないため、メインメソッドはそれを含んでいるクラスがインスタンス化されていなくても、実行される必要があるからです。

static クラス(static インナークラス)

クラスの中のクラス = インナークラス には3種類ある。

  • メンバクラス
  • ローカルクラス
  • 匿名クラス

staticメンバクラスは、メンバクラスの一つで、宣言場所はクラスブロックの中(フィールドやメソッドと同じ位置)
厳密にはstaticメンバクラスはインナークラスというより、まったく別クラスと表現したほうが正しい。

インナークラスを包含しているクラスを外部クラスと呼ぶ。
外部クラスやそのインスタンスとの関係が比較的薄く、外部クラスの static メンバにもアクセスできる。

class Outer { // 外部クラス

  // メンバクラス➀ static クラス
  static class StaticInner {
    private Integer in;

    public Integer getIn() {
      return in;
    }

    public void setIn(Integer in) {
      this.in = in;
    }
  }

  // メンバクラス➁ 厳密的なメンバクラス
  class Inner {
    private String str;

    public String getStr() {
      return str;
    }

    public void setStr(String str) {
      this.str = str;
    }
  }
}

無関係なクラスかつメインメソッドでの呼び出しは以下の通り

class Execute {
  public static void main(String[] args) {
    // static クラス
    Outer.StaticInner staticInner = new Outer.StaticInner();

    // 厳密的なメンバクラス
    Outer outer = new Outer();
    Outer.Inner inner = outer.new Inner();
  }
}

上記の例に含めてみましたが、厳密なメンバクラスは、外部クラスから生み出される個々のインスタンスと強い結びつきを持つため、外部クラスのインスタンスがなければ new ができません。static なモノではないため、非 static メンバにもアクセスが許容されます。

staticイニシャライザ

static {
  // 処理
}

staticイニシャライザは、クラスロード(.class ファイルがロード)される際に、一度だけ実行されるブロック。
あるクラスをインスタンス化する前や、メインメソッドよりも前に呼び出し実行したい処理を記述する。記述できるのはstaticなものに限る。

public final static String VALUE;

static {
  VALUE = makeValue();
} 

/**
 * 特定条件下で値を動的に生成する
 * @return value 生成した値
 */
private static String makeValue() {
  // omit
}

コンストラクタと static イニシャライザ

class Something {

  void printA() {
    System.out.print("t");
  }

  void printB() {
    System.out.print("e");
  }

  Something () {
    System.out.print("l");
    printB();
  }

  static {
    System.out.print("i");
  }
}

class StaticTest {
  static {
    System.out.print("T");
  }

  public static void main(String [] args) {
    System.out.print("o");
    new Something().printA();
  }
}

Kotllinのstaticメソッド

Kotlinではstaticメソッドはない。ただし、Companion Objectsという仕組みを使うことで実現可能。

class Foo {
    companion object {
        fun staticMethodTest() {
        }
    }
}

fun main() {
    Foo.staticMethodTest() //実行可能
}

Kotlinの定数

constを指定することでコンパイル時定数 (compile time constants) としてマークすることができる。

class Foo {
  companion object {
    val TEST_VAL1 = 1
    const val TEST_VAL = 2
  }
}

fun main() {
  println("TEST_VAL1 = ${Foo.TEST_VAL1}")
  println("TEST_VAL2 = ${Foo.TEST_VAL2}")
}

ただし、Javaでアクセスする場合にconstを指定している場合はFoo.TEST_VAL2でアクセスできる。
constしていない場合は、getTEST_VAL1()と呼ぶ。

const指定のメリット

  • コンパイル時定数となるので、パフォーマンスが良くなる。
  • Javaとの相互運用性が保てる

参考サイト

Takayuki ShojiTakayuki Shoji

Windowsショートカットキー

  • クリップボードの使い方:Windowsキー + v

スクリーンショット

  • PrintScreenキー:画面全体をスクリーンショットしてクリップボード上に保持
  • Alt + PrintScreen:現在開いているウインドウをスクリーンショットしてクリップボード上に保持
  • Windows + PrintScreen:画面全体をスクリーンショットして画像として保存。保存先はピクチャフォルダ
  • Windows + Alt + PrintScreen:現在開いているウインドウををスクリーンショットして画像として保存。保存先はビデオフォルダ
  • Windows + Alt + S:範囲を指定してスクリーンショットしてクリップボード上に保持

動画撮影

[Windows + G] でゲームバーを開き、赤枠部のボタンを押下する。もしくは、[Windows + Alt + G ]で録画

Takayuki ShojiTakayuki Shoji

リアクティブプログラミング(Reactive Programming)

リアクティブプログラミングとは、データが流れるように来ること(ストリーム)に着目し、データを受け取るたびに関連したプログラムが反応(リアクション)して処理を行うようにするプログラミングの考え方。
生成されるデータをすべてまとめて送信するのではなく、個々のデータが生成される度に順次送信していく。このようなデータの流れをデータストリームと言う。
データの生産側はデータを渡すところまでが責任範囲、どんなデータであれデータを渡すことが生産側の責務。

Takayuki ShojiTakayuki Shoji

SOLID原則

SOLIDとは、下記の5つのソフトウェア設計原則を並べたバクロニムである。

  1. Single Responsibility Principle:単一責任の原則
  2. Open/closed principle:オープン/クローズドの原則
  3. Liskov substitution principle:リスコフの置換原則
  4. Interface segregation principle:インターフェース分離の原則
  5. Dependency inversion principle:依存性逆転の原則

ソフトウェアエンジニアが知っておくべき設計原則として、『Clean Architecture』や『アジャイルソフトウェア開発の奥義』などの著作で有名な、Robert C.Martin氏(通称:ボブおじさん)によって書かれた論文が初出。

Single Responsibility Principle(単一責任原則)

Wikipediaによると下記のように記載される。

1つのクラスは、1つだけの責任を持たなければならない。

すなわち、ソフトウェアの仕様の一部を変更したときには、それにより影響を受ける仕様は、そのクラスの仕様でなければならない

参考サイト