2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Eclipse】コンパイルエラー/警告が発生する具体的ソースコード

Last updated at Posted at 2023-09-16

【概要】

Eclipseの「ウィンドウ -> 設定 -> Java -> コンパイラー -> エラー/警告」でエラー/警告が発生する具体的なコードを書きました。
一部コードの書き方が分からない項目もありましたが、分からなかったものについてはソース上に「実装方法不明」とコメントしています。

【環境】

Java 17
Eclipse Version: 2023-06 (4.28.0)、Build id: 20230608-1333

【エラー/警告の一覧表】

下記表の項番はソースコードでコメントしている項番と一致しています。

コード・スタイル

項番 エラー/警告 項目名
1-1 staticメンバーへの非staticアクセス
1-2 staticメンバーへの間接アクセス
1-3 インスタンス・フィールドへの限定されていないアクセス
1-4 エンクロージング型のアクセス不可メンバーへのアクセス
1-5 パラメータ代入
1-6 外部化されていないString(欠落している/未使用の$NON-NLS$タグ)
1-7 何も記述のない空のブロック
1-8 try-with-resourceで管理されていないリソース(1.7以上)
1-9 コンストラクター名を持つメソッド
1-10 staticにできるメソッド
1-11 潜在的にstaticにできるメソッド

潜在的なプログラミングの問題

項番 エラー/警告 項目名
2-1 同じ値の比較('x == x')
2-2 効果のない代入(例:「x = x」)
2-3 予期しない論理代入の可能性(たとえば、'if(a = b)')
2-4 ボクシングおよびアンボクシング変換
2-5 ストリング連結での文字列配列の使用
2-6 可変長引数の型の一致が不正確
2-7 ありそうもない'Object'を使用するコレクション・メソッドの引数型
2-7-1 予想される型に対して厳密な分析を実行する
2-8 ありそうもないequals()メソッドの引数型
2-9 空のステートメント
2-10 未使用のオブジェクト割り振り
2-11 enumの不完全な'switch'ケース
2-11-1 'default'ケースが存在する場合も知らせる
2-12 'default'ケースが欠落した'switch'
2-13 'switch'文のcaseのフォールスルー
2-14 隠れたcatchブロック
2-15 'finally'が正常に完了しない
2-16 デッド・コード(例:'if (false)')
2-17 リソース・リーク
2-18 潜在的なリソース・リーク
2-19 serialVersionUIDなしのシリアライズ可能クラス
2-20 継承されたメソッドのsynchronized修飾子の欠落
2-21 'equals()' をオーバーライドしているが 'hashCode()' がオーバーライドされていないクラス:

名前のシャドーイングおよび競合

項番 エラー/警告 項目名
3-1 フィールド宣言が他のフィールドまたは変数を隠蔽
3-2 ローカル変数宣言が他のフィールドまたは変数を隠蔽
3-2-1 コンストラクターまたはsetterメソッド・パラメーターを含む
3-3 型パラメーターが別の型を隠蔽
3-4 メソッドがパッケージ可視メソッドを非オーバーライド
3-5 protectedの'Object'メソッドと競合するインターフェース・メソッド

使用すべきではない制限されたAPI

項番 エラー/警告 項目名
4-1 使用すべきではないAPI
4-1-1 使用すべきではないコード内での使用すべきではないAPIの使用を知らせる
4-1-2 使用すべきではないメソッドのオーバーライドまたは実装を知らせる
4-2 除去とマークされた廃止予定のAPI
4-3 禁止された参照(アクセス・ルール)
4-4 阻止された参照(アクセス・ルール)

モジュール

項番 エラー/警告 項目名
5-1 APIリーク
5-2 不安定な名前が必要な自動モジュール

不要なコード

項番 エラー/警告 項目名
6-1 ローカル変数の値が未使用
6-2 メソッド・パラメーターの値が未使用
6-2-1 オーバーライドしたメソッドの実装を無視
6-3 未使用の型パラメーター
6-4 '@param'タグで未使用の文書化されたパラメーターを無視
6-5 例外パラメーターの値が未使用
6-6 未使用のインポート
6-7 未使用のprivateメンバー
6-8 不要な'else'ステートメント
6-9 不要なキャストまたは'instansof'操作
6-10 不要な例外スロー宣言
6-10-1 オーバーライドしたメソッドの実装を無視
6-10-2 '@throws'または'@exception'で文書化された例外を無視
6-10-3 'Exception'および'Throwable'を無視
6-11 未使用の'break'または'continue'ラベル
6-12 冗長なスーパー・インターフェース

総称型

項番 エラー/警告 項目名
7-1 未検査の総称型操作
7-2 raw型の使用
7-3 finalな型で制約された総称型パラメーター
7-4 冗長な型引数(1.7以上)
7-5 raw APIが原因で避けられない総称型問題を無視

注釈

項番 エラー/警告 項目名
8-1 '@Override'注釈の欠落
8-1-1 インターフェース・メソッドの実装を含める(1.6以上)
8-2 '@Deprecated'注釈の欠落
8-3 注釈をスーパー・インターフェースとして使用
8-4 '@SuppressWarnings'で処理されないトークン
8-5 '@SuppressWarnings'注釈の使用可能化
8-5-1 未使用の'@SuppressWarnings'トークン
8-5-2 関連するオプションが'無視'に設定され、完全には認識されない'未使用'ステータス
8-5-3 '@SuppressWarnings'でオプション・エラーを抑制

Null分析

項番 エラー/警告 項目名
9-1 nullポインター・アクセス
9-2 潜在的なnullポインター・アクセス
9-3 冗長なnull検査
9-4 null分析で'assert'を含める
9-5 注釈ベースのnull分析を使用可能にする
9-5-1 null仕様違反
9-5-2 null注釈およびnullインスタンスへの競合
9-5-3 非注釈型から@NonNull型への未検査変換
9-5-4 注釈付きのパラメーター化された型から注釈の少ないタイプへの安全でない変換
9-5-5 自由型変数のための悲観的な分析によって検出された問題
9-5-6 ライブラリーからの自由型変数の安全でない'@Nonnull'の解釈
9-5-7 冗長なnull注釈
9-5-8 オーバーライドするメソッドで注釈が付けられていない'@NonNull'パラメーター
9-5-9 パッケージの'@NonNullByDefault'注釈が欠落
9-5-10 null仕様のデフォルト注釈を使用する
9-5-11 null注釈の継承
9-5-12 フィールドの構文null分析を使用可能にする
9-5-13 すべてのビルド・パス・ロケーションで外部注釈を検索する

【GitHubにアップロードしたプロジェクト構成】

  • errors-warnings
    • Null分析以外のソースコード
  • errors-warnings-null-analysis
    • Null分析だけのソースコード(@org.eclipse.jdt.annotation.NonNullを使用するには、Springプロジェクトで作成する必要があったため)
  • unstableAutoModuleName
    • モジュールで利用するためのjar作成用のソースコード

【ソースコード】

errors-warningsプロジェクト

コード・スタイル
CodeStyle.java
package codestyle;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class CodeStyle extends CodeStyleParent {

	private static final int CODE_STYLE = 0;

	private void indirectStaticAccess() {
		CodeStyle codeStyle = new CodeStyle();
		// 1-1. staticメンバーへの非staticアクセス
		int a = codeStyle.CODE_STYLE;
	}

	private void staticAccessReceiver() {
		// 1-2. staticメンバーへの間接アクセス
		int a = CodeStyle.CODE;
	}

	private int codeStyle;

	private void unqualifiedFieldAccess() {
		// 1-3. インスタンス・フィールドへの限定されていないアクセス
		int a = codeStyle;
	}

	private void syntheticAccessEmulation() {
		EnclosingClass ec = new EnclosingClass();
		// 1-4. エンクロージング型のアクセス不可メンバーへのアクセス
		// おそらくJava8以前のバージョンにしないとエラー/警告が起きない
		// 少なくともJava8のバージョンではエラー/警告が起きることを確認済み
		int a = ec.a;
	}

	class EnclosingClass {
		private int a;
		int b;
	}

	private void parameterAssignment(int a) {
		// 1-5. パラメータ代入
		a = 1;
	}

	private void nonExternalizedStringLiteral() {
		// 1-6. 外部化されていないString(欠落している/未使用の$NON-NLS$タグ)
		String a = "a";
		int b = 1; //$NON-NLS-1$
	}

	private void undocumentedEmptyBlock(boolean can) {
		// 1-7. 何も記述のない空のブロック
		if (true) {
		}
	}

	private void explicitlyClosedAutoCloseable() throws IOException {
		// 1-8. try-with-resourceで管理されていないリソース(1.7以上)
		BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(".classpath"), "UTF-8"));
		try {
			String line;
			while ((line = reader.readLine()) != null) {
				System.out.println(line);
			}
		} catch (IOException e) {
			throw e;
		} finally {
			try {
				reader.close();
			} catch (IOException e) {
				throw e;
			}
		}
	}

	// 1-9. コンストラクター名を持つメソッド
	private void CodeStyle() {
	}

	// 1-10. staticにできるメソッド
	private void reportMethodCanBeStatic() {
		int a = 1;
	}

	// 1-11. 潜在的にstaticにできるメソッド
	public void reportMethodCanBePotentiallyStatic() {
		int a = CodeStyle.CODE;
	}
}
CodeStyleParent.java
package codestyle;

public class CodeStyleParent {
	public static final int CODE = 1;
}
潜在的なプログラミングの問題
ProgrammingProblem.java
package programmingproblem;

import java.io.BufferedReader;
import java.io.CharConversionException;
import java.io.Closeable;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.io.UncheckedIOException;
import java.nio.file.DirectoryIteratorException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

// 2-21. 'equals()'をオーバーライドしているが'hashCode()'がオーバーライドされていないクラス
public class ProgrammingProblem extends ProgrammingProblemParent {
	private void comparingIdentical(int a) {
		// 2-1. 同じ値の比較('x == x')
		if (a == a) {
		}
	}

	private void noEffectAssignment(int a) {
		// 2-2. 効果のない代入(例:「x = x」)
		a = a;
	}

	private void possibleAccidentalBooleanAssignment(boolean a, boolean b) {
		// 2-3. 予期しない論理代入の可能性(たとえば、'if(a = b)')
		if (a = b) {
		}
	}

	private void autoboxing(int a, Integer b) {
		// 2-4. ボクシングおよびアンボクシング変換
		// ボクシング変換
		Integer c = a;
		// アンボクシング変換
		int d = b;
	}

	private void noImplicitStringConversion() {
		// 2-5. ストリング連結での文字列配列の使用
		String a = "hello" + new char[] { 'w', 'o', 'r', 'l', 'd' };
	}

	private void varargsArgumentNeedCast() {
		// 2-6. 可変長引数の型の一致が不正確
		Arrays.asList(null);
	}

	private void unlikelyCollectionMethodArgumentType() {
		Map<String, String> a = new HashMap<>();
		// 2-7. ありそうもない'Object'を使用するコレクション・メソッドの引数型
		a.get(1);
	}
	
	private void unlikelyCollectionMethodArgumentTypeStrict(Object o) {
		Map<?, ?> a = new HashMap<>();
		// 2-7-1. 予想される型に対して厳密な分析を実行する にチェックあり
		a.get(o);
	}

	private void unlikelyEqualsArgumentType(Collection<Path> aaa) {
		// 2-8. ありそうもないequals()メソッドの引数型
		"abc".equals(1);
	}

	private void emptyStatement() {
		// 2-9. 空のステートメント
		;
	}

	private void unusedObjectAllocation() {
		// 2-10. 未使用のオブジェクト割り振り
		new ArrayList<>();
	}

	private enum Color {
		RED, GREEN, BLUE
	}

	private void incompleteEnumSwitch(Color color) {
		// 2-11. enumの不完全な'switch'ケース
		switch (color) {
		case RED:
			System.out.println("赤");
			break;
		case GREEN:
			System.out.println("緑");
			break;
		}

		// 2-11-1. 'default'ケースが存在する場合も知らせる にチェックあり
		switch (color) {
		case RED:
			System.out.println("赤");
			break;
		case GREEN:
			System.out.println("緑");
			break;
		default:
			System.out.println("その他");
		}
	}

	private void missingDefaultCase(Color color) {
		// 2-12. 'default'ケースが欠落した'switch'
		switch (color) {
		case RED:
			System.out.println("赤");
			break;
		case GREEN:
			System.out.println("緑");
			break;
		}
	}

	private void fallthroughCase(Color color) {
		switch (color) {
		case RED:
			System.out.println("赤");
		// 2-13. 'switch'文のcaseのフォールスルー
		case GREEN:
			System.out.println("緑");
			break;
		}
	}

	private void hiddenCatchBlock() {
		try {
			throw new CharConversionException();
		} catch (CharConversionException e) {
		// 2-14. 隠れたcatchブロック
		} catch (IOException e) {
		}
	}

	private void finallyBlockNotCompletingNormally() throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(".classpath"), "UTF-8"));
		try {
			String line;
			while ((line = reader.readLine()) != null) {
				System.out.println(line);
			}
		} catch (IOException e) {
			throw e;
		// 2-15. 'finally'が正常に完了しない
		} finally {
			try {
				reader.close();
				return;
			} catch (IOException e) {
				throw e;
			}
		}
	}

	private void deadCode() {
		if (true) {
		// 2-16. デッド・コード(例:'if (false)')
		} else {
		}
	}

	private void unclosedCloseable() throws IOException {
		// 2-17. リソース・リーク
		BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(".classpath"), "UTF-8"));
		try {
			String line;
			while ((line = reader.readLine()) != null) {
				System.out.println(line);
			}
		} catch (IOException e) {
			throw e;
		}
	}
	
	// java.nio.file.Filesのlist(Path dir)の実装をそのままコピーしたもの
	private Stream<Path> potentiallyUnclosedCloseable(Path dir) throws IOException {
        DirectoryStream<Path> ds = Files.newDirectoryStream(dir);
        try {
            final Iterator<Path> delegate = ds.iterator();

            // Re-wrap DirectoryIteratorException to UncheckedIOException
            Iterator<Path> iterator = new Iterator<>() {
                @Override
                public boolean hasNext() {
                    try {
                        return delegate.hasNext();
                    } catch (DirectoryIteratorException e) {
                        throw new UncheckedIOException(e.getCause());
                    }
                }
                @Override
                public Path next() {
                    try {
                        return delegate.next();
                    } catch (DirectoryIteratorException e) {
                        throw new UncheckedIOException(e.getCause());
                    }
                }
            };

            Spliterator<Path> spliterator =
                Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT);
            // 2-18. 潜在的なリソース・リーク
            return StreamSupport.stream(spliterator, false)
                                .onClose(asUncheckedRunnable(ds));
        } catch (Error|RuntimeException e) {
            try {
                ds.close();
            } catch (IOException ex) {
                try {
                    e.addSuppressed(ex);
                } catch (Throwable ignore) {}
            }
            throw e;
        }
	}
	
    private static Runnable asUncheckedRunnable(Closeable c) {
        return () -> {
            try {
                c.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        };
    }
	

	// 2-19. serialVersionUIDなしのシリアライズ可能クラス
	private class MissingSerialVersion implements Serializable {
	}

	@Override
	// 2-20. 継承されたメソッドのsynchronized修飾子の欠落
	protected void synchronizedMethod() {
	}

	@Override
	public boolean equals(Object obj) {
		return true;
	}
}
ProgrammingProblemParent.java
package programmingproblem;

public class ProgrammingProblemParent {
	protected synchronized void synchronizedMethod() {
	}
}

名前のシャドーイングおよび競合
NameShadow.java
package nameshadow;

import nameshadow.override.NameShadowParent;

public class NameShadow extends NameShadowParent {
	// 3-1. フィールド宣言が他のフィールドまたは変数を隠蔽
	private int a;

	private void localVariableHiding() {
		// 3-2. ローカル変数宣言が他のフィールドまたは変数を隠蔽
		int a;
	}

	// 3-2-1. コンストラクターまたはsetterメソッド・パラメーターを含む にチェックあり
	private NameShadow(int a) {
	}

	// 3-3. 型パラメーターが別の型を隠蔽
	private class Outer<T> {
		class Inner<T> {
		}
	}

	// 3-4. メソッドがパッケージ可視メソッドを非オーバーライド
	void overridingPackageDefaultMethod() {
	}
}
NameShadowParent.java
package nameshadow.override;

public abstract class NameShadowParent {
	protected int a;
	
	void overridingPackageDefaultMethod() {
	}
}
NameShadowInterface.java
package nameshadow;

public interface NameShadowInterface {
	// 3-5. protectedの'Object'メソッドと競合するインターフェース・メソッド
	int clone();
}
使用すべきではない制限されたAPI
DeprecatedApi.java
package deprecatedapi;

import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

public class DeprecatedApi extends DeprecatedApiParent {
	private void deprecation() {
		// 4-1. 使用すべきではないAPI
		Character.isJavaLetter('a');
	}
	
	
	@Deprecated
	public void deprecationInDeprecatedCode() {
		// 4-1-1. 使用すべきではないコード内での使用すべきではないAPIの使用を知らせる にチェックあり
		super.deprecationWhenOverridingDeprecatedMethod();
	}
	
	@Override
	// 4-1-2. 使用すべきではないメソッドのオーバーライドまたは実装を知らせる にチェックあり
	public void deprecationWhenOverridingDeprecatedMethod() {
	}
	
	// 4-2. 除去とマークされた廃止予定のAPI は実装方法不明
	
	private void forbiddenReference() throws URISyntaxException {
		// 4-3. 禁止された参照(アクセス・ルール)
		// ビルドパスのアクセスルールに追加が必要
		URI uri = new URI("https://qiita.com");
	}
	
	private void discouragedReference() throws MalformedURLException  {
		// 4-4. 阻止された参照(アクセス・ルール)
		// ビルドパスのアクセスルールに追加が必要
		URL url = new URL("https://qiita.com");
	}
}
DeprecatedApiParent.java
package deprecatedapi;

public class DeprecatedApiParent {
	@Deprecated
	public void deprecationWhenOverridingDeprecatedMethod() {
	}
}
モジュール
Module.java
package modules;

public class Module {
	
	// 5-1. APIリーク
	public ApiLeak apiLeak() {
		return new ApiLeak();
	}
	
	private class ApiLeak {
	}
}
module-info.java
module modules {
	exports modules;
	// 5-2. 不安定な名前が必要な自動モジュール
	requires unstableAutoModuleName;
}
不要なコード
UnNecessaryCode.java
package unnecessarycode;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
// 6-6. 未使用のインポート
// ファイル保存時に不要なインポートが自動削除される場合があるため、コメントアウトしている
// 警告確認時はコメントアウトを外す必要がある
// import java.util.regex.Matcher;

//6-12. 冗長なスーパー・インターフェース
public class UnNecessaryCode extends UnNecessaryCodeParent implements UnNecessaryCodeInterface {

	private void unusedLocal() {
		// 6-1. ローカル変数の値が未使用
		int a;
	}

	// 6-2. メソッド・パラメーターの値が未使用
	private void unusedParameter(int a) {
	}

	@Override
	// 6-2-1. オーバーライドしたメソッドの実装を無視 にチェックなし
	public void unusedParameterWhenOverridingConcrete(int a) {
	}

	// 6-3. 未使用の型パラメーター
	private <E> void unusedTypeParameter(List<?> list) {
	}

	/**
	 * 
	 * @param <E>
	 * @param list
	 */
	// 6-3. 未使用の型パラメーター
	// 6-4. '@param'タグで未使用の文書化されたパラメーターを無視 にチェックなし
	private <E> void unusedParameterIncludeDocCommentReference(List<?> list) {
	}

	private void unusedExceptionParameter() {
		try (BufferedReader twrReader = new BufferedReader(
				new InputStreamReader(new FileInputStream(".classpath"), "UTF-8"));) {
			String line;
			while ((line = twrReader.readLine()) != null) {
				System.out.println(line);
			}
		// 6-5. 例外パラメーターの値が未使用
		} catch (IOException e) {
		}
	}
	
	// 6-7. 未使用のprivateメンバー
	private int a;

	private void unnecessaryElse() {
		if (true) {
			return;
		// 6-8. 不要な'else'ステートメント
		} else {
		}
	}

	private void unnecessaryTypeCheck() {
		// 6-9. 不要なキャストまたは'instansof'操作
		int a = (int) 1;
	}

	// 6-10. 不要な例外スロー宣言
	private void unusedDeclaredThrownException() throws IOException {
	}

	@Override
	// 6-10-1. オーバーライドしたメソッドの実装を無視 にチェックなし
	public void unusedDeclaredThrownExceptionWhenOverriding() throws IOException {
	}
	
	/**
	 * 
	 * @throws IOException
	 */
	// 6-10-2. '@throws'または'@exception'で文書化された例外を無視 にチェックなし
	private void unusedDeclaredThrownExceptionIncludeDocCommentReference() throws IOException {
	}

	// 6-10-3. 'Exception'および'Throwable'を無視 にチェックなし
	private void unusedDeclaredThrownExceptionExemptExceptionAndThrowable() throws Exception {
	}

	// 6-11. 未使用の'break'または'continue'ラベル
	private void unusedLabel() {
		label: for (int i = 1; i < 10; i++) {
		}
	}
}
UnNecessaryCodeParent.java
package unnecessarycode;

import java.io.IOException;

public class UnNecessaryCodeParent implements UnNecessaryCodeInterface {
	public void unusedParameterWhenOverridingConcrete(int a) {
	}
	
	public void unusedDeclaredThrownExceptionWhenOverriding() throws IOException {
	}

	@Override
	public void redundantSuperinterface() {
	}
}
UnNecessaryCodeInterface.java
package unnecessarycode;

public interface UnNecessaryCodeInterface {
	public void redundantSuperinterface();
}
総称型
Generics.java
package generics;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Generics extends GenericsParent {
	private void uncheckedTypeOperation() {
		// 7-1. 未検査の総称型操作
		List<Integer> a = new ArrayList(Arrays.asList(1));
	}

	private void rawTypeReference() {
		// 7-2. raw型の使用
		List a;
	}

	// 7-3. finalな型で制約された総称型パラメーター
	private <T extends String> T finalParameterBound() {
		return null;
	}

	private void redundantSpecificationOfTypeArguments() {
		// 7-4. 冗長な型引数(1.7以上)
		List<Integer> a = new ArrayList<Integer>();
	}

	@Override
	// 7-2. raw型の使用
	// 7-5. raw APIが原因で避けられない総称型問題を無視 にチェックなし
	public void unavoidableGenericTypeProblems(ArrayList list) {
	}
}
GenericsParent.java
package generics;

import java.util.ArrayList;

public class GenericsParent {
	public void unavoidableGenericTypeProblems(ArrayList list) {
	}
}
注釈
Annotation.java
package annotation;

public class Annotation extends AnnotationParent implements AnnotationInterface {

	// 8-1. '@Override'注釈の欠落
	public void missingOverrideAnnotation() {
	}
	
	// 8-1-1. インターフェース・メソッドの実装を含める(1.6以上) にチェックあり
	public void missingOverrideAnnotationForInterfaceMethodImplementation() {
	}

	/**
	 * @deprecated
	 */
	// 8-2. '@Deprecated'注釈の欠落
	private void missingDeprecatedAnnotation() {
	}

	// 8-4. '@SuppressWarnings'で処理されないトークン
	@SuppressWarnings(value = { "test" })
	private void unhandledWarningToken() {
	}

	// 8-5. '@SuppressWarnings'注釈の使用可能化
	@SuppressWarnings("deprecation")
	private void suppressWarnings() {
		Character.isJavaLetter('a');
	}

	// 8-5. '@SuppressWarnings'注釈の使用可能化 にチェックあり
	// 8-5-1. 未使用の'@SuppressWarnings'トークン
	@SuppressWarnings("deprecation")
	private void unusedWarningToken() {
	}

	// 6-7. 未使用のprivateメンバー を"無視"に設定
	// 8-5. '@SuppressWarnings'注釈の使用可能化 にチェックあり
	// 8-5-2. 関連するオプションが'無視'に設定され、完全には認識されない'未使用'ステータス
	@SuppressWarnings("unused")
	private void suppressWarningsNotFullyAnalysed() {
	}

	@SuppressWarnings("all")
	private void suppressOptionalErrors(int a) {
		// 2-1. 同じ値の比較('x == x')
		// 8-5. '@SuppressWarnings'注釈の使用可能化 にチェックあり
		// 8-5-3. '@SuppressWarnings'でオプション・エラーを抑制 にチェックなし
		if (a == a) {
		}
	}
	
	@Override
	public Class<? extends java.lang.annotation.Annotation> annotationType() {
		return null;
	}
}
AnnotationParent.java
package annotation;

public class AnnotationParent {
	public void missingOverrideAnnotation() {
	}
}
AnnotationInterface.java
package annotation;

// 8-3. 注釈をスーパー・インターフェースとして使用
public interface AnnotationInterface extends Override {
	public void missingOverrideAnnotationForInterfaceMethodImplementation();
}

errors-warnings-null-analysisプロジェクト

Null分析
NullAnalysis.java
package com.example.demo.nullanalysis;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jdt.annotation.NonNullByDefault;

public class NullAnalysis {
	private void nullReference() {
		String a = null;
		// 9-1. nullポインター・アクセス
		a.length();
	}

	private void potentialNullReference(String a) {
		boolean isNull = a == null;
		if (isNull) {
			// 9-2. 潜在的なnullポインター・アクセス
			a.length();
		}
	}
	
	private void redundantNullCheck() {
		String a = "test";
		int b = a.length();
		// 9-3. 冗長なnull検査
	    if (a == null) {
	    }
	}
	
	private void includeNullInfoFromAsserts(String a) {
	    assert a != null;
	    // 9-3. 冗長なnull検査
	    // 9-4. null分析で'assert'を含める
	    if (a != null) {
	    }
	}
	
	private void nullSpecViolation(@org.eclipse.jdt.annotation.NonNull String a) {
    	// 9-5-1. null仕様違反
    	a = null;
    }

	private void nullAnnotationInferenceConflict(boolean can) {
		@org.eclipse.jdt.annotation.NonNull
		String a = "a";
		String b = "b";
		
		if (can) {
			b = null;
		}
		
		// 9-5-2. null注釈およびnullインスタンスへの競合
		a = b;
    }
    
	private void nullUncheckedConversion(boolean can) {
		@org.eclipse.jdt.annotation.NonNull
		String a;
		
		if (can) {
			// 9-5-3. 非注釈型から@NonNull型への未検査変換
			a = nullUncheckedConversionSub();
		}
    }
    
	private String nullUncheckedConversionSub() {
    	return null;
    }
    
	private void annotatedTypeArgumentToUnannotated() {
    	List<@org.eclipse.jdt.annotation.NonNull String> a = new ArrayList<>();
    	List<String> b = new ArrayList<>();
    	
    	// 9-5-4. 注釈付きのパラメーター化された型から注釈の少ないタイプへの安全でない変換
    	b = a;
    }
    
	private class PessimisticNullAnalysisForFreeTypeVariables<T extends Number> {
		int consume(T a) {
			// 9-5-5. 自由型変数のための悲観的な分析によって検出された問題
			return a.intValue();
		}

		T provide() {
			// 9-5-5. 自由型変数のための悲観的な分析によって検出された問題
			return null;
		}
	}
	
	// 9-5-6. ライブラリーからの自由型変数の安全でない'@Nonnull'の解釈 は実装方法不明
	
	@NonNullByDefault
	private class RedundantNullAnnotation {
		// 9-5-7. 冗長なnull注釈
		@org.eclipse.jdt.annotation.NonNull
		public String redundantNullAnnotation() {
			return "a";
		}
	}
	
	@NonNullByDefault
	private class NonnullParameterAnnotationDroppedParent {
		public void nonnullParameterAnnotationDropped(String a) {
		}
	}
	
	private class NonnullParameterAnnotationDropped extends NonnullParameterAnnotationDroppedParent {
		@Override
		// 9-5-8. オーバーライドするメソッドで注釈が付けられていない'@NonNull'パラメーター
		// 9-5-11. null注釈の継承 にチェックを付けるとエラーがなくなる
		public void nonnullParameterAnnotationDropped(String a) {
		}
	}
	
	@org.eclipse.jdt.annotation.Nullable
	private Object a;

	private void syntacticNullAnalysisForFields() {
		if (a != null)
			// 9-2. 潜在的なnullポインター・アクセス
			// 9-5-12. フィールドの構文null分析を使用可能にする にチェックを付けるとエラーがなくなる
			a.toString();
	}
	
	// 9-5-13. すべてのビルド・パス・ロケーションで外部注釈を検索する は実装方法不明
}
MissingNonNullByDefaultAnnotation.java
// 9-5-9. パッケージの'@NonNullByDefault'注釈が欠落
public class MissingNonNullByDefaultAnnotation {

}

【必要だったプロジェクト設定】

使用すべきではない制限されたAPI

下記項目についてはアクセス・ルールの追加が必要でした。

  • 4-3. 禁止された参照(アクセス・ルール)
  • 4-4. 阻止された参照(アクセス・ルール)

image.png

モジュール

下記項目についてはunstableAutoModuleNameプロジェクトをjarにして、外部jarの追加が必要でした。

  • 5-2. 不安定な名前が必要な自動モジュール

image.png

【参考サイト】

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?