先日、 Java のコードを書いているときに Eclipse のコード ・ アシストが効かなくなる事態が発生しました。
ウェブで検索してみると、 .settings
の中にあるファイルの content_assist_disabled_computers
の行をコメントアウトするとか、 Eclipse の ContentAssist 設定で Java Proposals のチェックが外れていないか確認する、 といった解決策が見つかります。しかし、 いずれの方法を試しても解決せず。
さらに調べてみたところ、 Java の複雑な構文を使用しているとコード ・ アシストが効かなくなるバグが Eclipse にあることが分かりました。(確認に使用したバージョンは Eclipse 2019-03 です。)
特定のソースコードのみコード・アシストが効かない
複数の .java
ファイルがあり、 その中の 1 つのファイルだけがコード ・ アシストが効かない状況になっていました。このことから、 Eclipse の環境設定ではなく、 このソースコード自体が原因を引き起こしているのではないかと考えました。(このファイルに構文エラーは含まれておらず、 コンパイルはできる状態にはなっています。)
いろいろと試していくと、 ソースコードの前半ではコード ・ アシストが機能する、 ソースコードの後半ではコード ・ アシストが機能しない、 ということが分かってきました。ソースコードにおかしな記述があって、 それ以降ではコード ・ アシストが機能しなくなっているようです。
範囲を絞り込んでいって分かったのは、 以下の条件を満たす複雑な構文を使用しているとコード ・ アシストが機能しなくなるということでした。
- フィールドに匿名クラスを使用している。
- インスタンス ・ イニシャライザを使用している。
- ラムダ式または匿名クラスを引数として使用している。
たとえば、 以下のコードです。
Eclipseのコード・アシストが効かなくなるコード例 1public class Sample {
private Object anonymous = new Object() {
{
// ここまではコード・アシストが機能します。
new Thread(() -> {
});
// これ以降はコード・アシストが機能しません。
}
};
}
ラムダ式の手前では、 コード ・ アシストが機能しています。
ラムダ式よりも後ろでは、 コード ・ アシストが機能しなくなります。
上記の例では、 Thread
クラスのコンストラクタ引数に Runnable
インターフェースをラムダ式で指定しています。ラムダ式の代わりに匿名クラスを使用するように書き直してもコード ・ アシストが機能しない問題は改善しませんでした。
Eclipseのコード・アシストが効かなくなるコード例 2public class Sample {
private Object anonymous = new Object() {
{
// ここまではコード・アシストが機能します。
new Thread(new Runnable() {
@Override
public void run() {
}
});
// これ以降はコード・アシストが機能しません。
}
};
}
コンストラクタ引数ではなくメソッドの引数として使用する場合もダメでした。
Eclipseのコード・アシストが効かなくなるコード例 3public class Sample {
private Object anonymous = new Object() {
{
// ここまではコード・アシストが機能します。
Executors.callable(new Runnable() {
@Override
public void run() {
}
});
// これ以降はコード・アシストが機能しません。
}
};
}
コード・アシストが機能するように書き直した
以下のようにステートメントを分けて書いたところ、 コード ・ アシストが機能しました。
Eclipseのコード・アシストが機能したコード例public class Sample {
private Object anonymous = new Object() {
{
Runnable r = () -> {};
new Thread(r);
// ここでコード・アシストが機能しました!
}
};
}
他にもインスタンス ・ イニシャライザの代わりにコンストラクタに処理を書く、 匿名クラスの代わりに内部クラスを使う、 といった変更でも事象を解決することができました。
コード ・ アシストは文脈 (コンテキスト) によって表示される内容が変わります。複雑な入れ子を使ってコードを書くとコンテキストが分からなくなってしまうバグなのかもしれません。
なお、 このコード ・ アシストが効かなくなってしまう問題については、 Eclipse の Bugzilla に報告しておきました。改善されるといいですね。