Eclipse

公式サイトから入れた。ああ~、、こーゆーのか。これプラグイン入れないと環境としてはキツイなあ。。これはVS Codeもそうなんだけど、Visual Studio慣れちゃってるとね。。
一応バージョンは2024で、エディションはなんか色々出来そうなのでfor Enterprise Java and Web Developersを試すことにした。

プラグインを恐らく入れる箇所は2つあり、~\eclipse\[version]\eclipse(恐らく通常のクラシックスタイルで、Pleiadesはこういうのに突っ込んで置き換えるスタイル)と~\eclipse-workspace\.metadata\.plugins(マーケットプレイス経由)になる。~\.eclipseにキャッシュとかが置かれる。

とりまカスタムしたところ

  • Pleiadesから日本化プラグインを入手する。Windows版のsetup.exeからパス入れ込めば自動設定してくれる
    • なぜかスタートのショートカットが死んだので貼り直す
    • 一応他の日本語化の方法としてはBabelがあるらしい
  • Darkest Dark Theme with DevStyleを入れる
    • このプラグインは使用感として相当デカい。一気に使い心地がVisual Studioっぽくなる。
    • Eclipse Color ThemeからVisual Studio 11 Darkを読ませてテーマ設定する
  • Vrapperを入れてVim打ちにする
    • これも結構重要。Vim打ち出来ないとプログラムできん、、
  • Copilot4EclipseでGitHub Copilot有効化可能
  • 設定>一般>外観>基本>テキスト・フォントでUDEV Gothic NF11を使う
    • これは趣味志向だがフォントを落とす必要がある。サイズは個人的に11がしっくりくる
  • 設定>Java>エディター>コンテンツアシスト>自動有効化をセットしトリガーに.abcdefghijkemnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_を設定
    • 結構重要。てかなんでデフォが.だけなんだ

とりあえず、このあたりさえやれば最低限すぎるところはOKそうだが、意外と時間がかかった。インストールが長いね、Javaツールは。

現状プロジェクトの構成方法が謎だが、とりあえずJavaプロジェクトを適当に入力し、Hello Worldは出来た。

恐らくモダンな文法系

機能確認。どんなところからやってるんだ。

恐らく機能としては最新の方であろう。

  • record class
    • 要はC#のrecordなのだが、今んとこPythonのdataclassっぽい認識
  • Annotation
    • 要はC#のAttribute。恐らくフレームワーク系で頻出。あと継承の@overrideが頻出なのだろう
    • どうやらgetClass()でリフレクションっぽいのが出来るらしいのでそれで取れそう
  • Stream API
    • Listなどのインターフェース型に載っかってるらしい。要はLinqの最低限っぽい実装に見える
    • stream()すると返ってくるのでチェーンで組む感じ
  • Optional<T>
    • 流行りのnull許容型。また未調査だが恐らくオプショナルチェインは現在載っていない
    • oforElseなどの判定系メソッドで組み込んでやっていく系。Javaは全部メソッドやなあ
  • メソッド参照::
    • 私はこれを静的メソッドのアクセス修飾子だと最初思った。要はx -> x.method()の糖衣構文らしい
    • statlcだろうがインスタンスクラスだろうがT::methodで解釈してくれるっぽい
    • どうでも良いが、Javaのラムダは->である。恐らくswitch returnとかパターンマッチングっぽい文法もモダンなのだと載っかっている
  • var
    • 自動型推論。C#のvarでありC++のauto
    • これは好き好みありそうなヤツね。型推論の能力はいかほどか。メインストリームのJava文化はどっちなのかな?C#で慣れすぎてて今のところはガシガシ使うだろう
    • C#式に慣れちゃってるのでそっちがフツーに見えてしまうんだが、var使わないならList<String> list = ArrayList<>();なんてテンプレート型の省略式も書ける。うーん、色々書き方あるなあ

確認コードは以下。

// declare annotation
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
protected @interface MyAnnotation {
	String value();
}

// record class
protected static record Person(String name, int age) {
	// method with annotation
	@MyAnnotation("Hello Attribute")
	public void sayHello() {
		var val = this.getMyAnnotationValue().orElse("");
		System.out.println("Hello, my name is " + name + " and I am " + age + " years old. And Attr:" + val);
	}
	
	// nullable type
	private Optional<String> getMyAnnotationValue() {
		var val = ""; 
		// reflection
		for (var method : this.getClass().getDeclaredMethods()) {
			var annotation = method.getAnnotation(MyAnnotation.class);
			if (annotation != null) {
				val = annotation.value();
				break;
			}
		}
		return Optional.of(val);
	}
}

public static void main(String[] args) {
	var persons = new ArrayList<Person>();
	persons.add(new Person("Alice", 25));
	persons.add(new Person("Bob", 30));
	persons.add(new Person("Charlie", 35));
	
	// stream API
	var filteredPersons = persons.stream().filter(p -> p.age() >= 30).toList();
	filteredPersons.forEach(Person::sayHello);
}