2

私はJava 8が初めてで、Null型の注釈とオプションを試しています。

以下の例では、クラスではなく String を使用しており、何かを呼び出すためだけに toUpperCase を呼び出しています。私の場合、実際にはパラメーターを渡す関数を呼び出しています (したがって、:: 演算子やマップを使用できるとは思わないでください)。 )。

Eclipse では、Java - Compiler - Errors/Warnings - Null Analysis Errors がオンになっています。

以下の私のテストコード:

public void test1(@Nullable String s) {
    // the 2nd s2 has a Potential null pointer access error. 
    // I was hoping ifPresent would imply NonNull
    Optional.ofNullable(s).ifPresent(s2 -> s2.toUpperCase());
}

@Nullable 
public String getSomeString() {
    return null;
}

public void test2() {
    String s = getSomeString();

    // This is fine, unlike the first example, I would have assumed that
    // it would know s was still nullable and behave the same way.
    Optional.ofNullable(s).ifPresent(s2 -> s2.toUpperCase());
}

Eclipse 型の null アノテーションと Optional.ifPresent を使用するとうまくいかないようです。

このようなものを機能させるために時間を無駄にしていますか? ゲッターを一時変数に割り当ててからnullかどうかをチェックし、そうでない場合は関数を呼び出すことに戻る必要がありますか?

4

2 に答える 2

2

JDT のヌル解析では、JRE やその他のライブラリのすべてのメソッドのセマンティクスを知ることができません。したがって、 への呼び出しを見ても結論は導き出されませんifPresent。これはOptional、分析がメソッドofNullable

<T> Optional<@NonNull T> ofNullable(@Nullable T value)

外部注釈は、2015 年 6 月 24 日にリリースされた Eclipse Mars からサポートされています。ヘルプ: 外部 null 注釈の使用 を参照してください。

問題の 2 つのバリアントの違いは、null 分析が Java 8 の型推論とどのように統合されているかによるものです。バリアント (1)sには type があり@Nullable Stringます。ifPresentこの型が型推論中に使用されると、引数も null 可能であると結論付けられます。バリアント (2) shas type String(フロー分析では、 からの初期化後に null になる可能性があることがわかりますgetSomeString)。注釈なしの型Stringは、バリアント (1) と同じ結論への型推論を支援するほど強力ではありません (ただし、これは JDT の将来のバージョンで改善される可能性があります)。

于 2015-06-18T21:37:42.143 に答える
1

まず、公開されているJava 8 SDK@Nullableの一部にならない継ぎ目。インポートしたパッケージを見てください: .com.sun.istack.internal.Nullable

2番目: 私はあなたの方法の両方を実行しました:test1(null)そしてtest2()、異常なことは何も起こりませんでした. すべてが順調でした(予想どおり)。それで、あなたは何を観察しましたか?

run test1(null)=> ラムダ式の実行なし。

test2() を実行 => ラムダ式の実行なし。

テスト用にコードを次のように変更しました。

public void test1(@Nullable String s) {
    Optional.ofNullable(s).ifPresent(s2 -> System.out.println("executed"));
}

public void test2() {
    String s = getSomeString();
    Optional.ofNullable(s).ifPresent(s2 -> System.out.println("executed"));
}
于 2015-06-18T11:20:42.967 に答える