判定 integer java 回避する!= null文



15 Answers

JetBrains IntelliJ IDEA 、Eclipse、NetbeansのようなJava IDE、またはfindbugsのようなツールを使用する(または使用する予定がある)場合、注釈を使用してこの問題を解決できます。

基本的には、 @Nullable@NotNullます。

次のように、メソッドとパラメータで使用できます。

@NotNull public static String helloWorld() {
    return "Hello World";
}

または

@Nullable public static String helloWorld() {
    return "Hello World";
}

2番目の例はコンパイルされません(IntelliJ IDEA)。

別のコードで最初のhelloWorld()関数を使用すると、次のようになります。

public static void main(String[] args)
{
    String result = helloWorld();
    if(result != null) {
        System.out.println(result);
    }
}

IntelliJ IDEAコンパイラは、 helloWorld()関数がnull返すことはないので、チェックが役に立たないことを伝えます。

パラメータの使用

void someMethod(@NotNull someParameter) { }

次のようなものを書くと

someMethod(null);

これはコンパイルされません。

@Nullableを使った最後の例

@Nullable iWantToDestroyEverything() { return null; }

これを行う

iWantToDestroyEverything().something();

そして、これは起こらないと確信することができます。 :)

コンパイラに通常よりも何かをチェックさせ、より強くなるように契約を強制するのは良い方法です。 残念ながら、すべてのコンパイラでサポートされているわけではありません。

IntelliJ IDEA 10.5以降では、他の@Nullable @NotNull実装のサポートが追加されました。

ブログ投稿を見るもっと柔軟で設定可能な@ Nullable / @ NotNullアノテーション

java int 未入力チェック

私はobject != nullを使用object != null NullPointerExceptionを避けるために多くのobject != null

これには良い選択肢がありますか?

例えば:

if (someobject != null) {
    someobject.doCalc();
}

これにより、オブジェクトがnullかどうかが不明な場合にNullPointerExceptionを回避できます。

受け入れられた回答は古いかもしれないことに注意してhttps://.com/a/2386013/12943 。最近のアプローチについてはhttps://.com/a/2386013/12943を参照してhttps://.com/a/2386013/12943 。




うわー、私はNullObject patternを推奨する57の異なる方法があるときに別の答えを加えるのはほとんど嫌いですが、この質問に興味がある人は、Java 7のテーブルに「null」を追加する提案があることを知りたいかもしれないと思います「セーフ・ハンドリング」 - if-not-equal-nullロジックのための合理化された構文。

Alex Millerの例は次のようになります。

public String getPostcode(Person person) {  
  return person?.getAddress()?.getPostcode();  
}  

?. 左側の識別子がヌルでない場合にのみ参照解除することを意味し、そうでない場合は残りの式をnullとして評価しnull 。 Java PosseのメンバーDick WallやDevoxx有権者のような人々は、この提案を本当に愛していますが、実際にはnullをセンチネル値として使用することを実際に促すという理由で反対もあります。

アップデート: Java 7のnullセーフな演算子のproposedProject Coinに提出されました 構文は上記の例とは少し異なりますが、同じ考え方です。

更新: null安全な演算子の提案は、Project Coinには入れませんでした。 したがって、Java 7ではこの構文は見られません。




この状況のた​​めだけに -

equalsメソッドを呼び出す前に変数がnullかどうかをチェックしません(以下の文字列比較の例を参照)。

if ( foo.equals("bar") ) {
 // ...
}

fooが存在しない場合、 NullPointerExceptionします。

このようにStringを比較すると、それを避けることができます:

if ( "bar".equals(foo) ) {
 // ...
}



あなたがチェックしているオブジェクトの種類に応じて、apacheコモンズのいくつかのクラスを使うことができるかもしれません: apache commons langapache commons collections

例:

String foo;
...
if( StringUtils.isBlank( foo ) ) {
   ///do something
}

または(あなたがチェックする必要があるものに応じて):

String foo;
...
if( StringUtils.isEmpty( foo ) ) {
   ///do something
}

StringUtilsクラスは多くのうちの1つです。 ヌルの安全な操作を行うコモンズにはかなりのクラスがあります。

ここでは、apacheライブラリ(commons-lang-2.4.jar)をインクルードするときに、Javaでnull valallationを使用する方法の例を示します。

public DOCUMENT read(String xml, ValidationEventHandler validationEventHandler) {
    Validate.notNull(validationEventHandler,"ValidationHandler not Injected");
    return read(new StringReader(xml), true, validationEventHandler);
}

また、Springを使用している場合、Springもパッケージと同じ機能を持ちます(library(spring-2.4.6.jar)

この静的クラスをSpring(org.springframework.util.Assert)から使用する方法の例

Assert.notNull(validationEventHandler,"ValidationHandler not Injected");



私は "失敗高速"のファンです。 自分自身に尋ねます - パラメータがnullの場合に役立つ何かをしていますか? その場合にコードが行うべきことについて明確な答えがない場合、つまり、最初はnullであってはならず、無視してNullPointerExceptionをスローすることができます。 呼び出し側のコードは、NPEをIllegalArgumentExceptionと同じように理解しますが、予期せぬその他の不測の事態を実行しようとするコードではなく、NPEがスローされた場合に、開発者がデバッグして何がうまくいかないかを理解することが容易になりますロジック - 最終的にはアプリケーションが失敗することになります。




時には、対称操作を定義するパラメータを操作するメソッドがあります。

a.f(b); <-> b.f(a);

bがnullになることができないことが分かっていれば、それを入れ替えることができます。 これはequalsにとって最も便利です: foo.equals("bar");代わりにfoo.equals("bar"); より良い"bar".equals(foo);




Java 7には、 requireNonNull()メソッドがある新しいjava.util.Objectsユーティリティクラスがあります。 引数がnullの場合はNullPointerExceptionがスローされますが、コードが少しクリアされます。 例:

Objects.requireNonNull(someObject);
someObject.doCalc();

このメソッドは、コンストラクタ内の代入の直前にcheckingのに最も便利です。コンストラクタを使用するたびに、次の3行のコードを保存できます。

Parent(Child child) {
   if (child == null) {
      throw new NullPointerException("child");
   }
   this.child = child;
}

〜になる

Parent(Child child) {
   this.child = Objects.requireNonNull(child, "child");
}



最終的に、この問題を完全に解決する唯一の方法は、別のプログラミング言語を使用することです。

  • Objective-Cでは、メソッドを呼び出すのと同等の処理を行うことができますが、nil何も起こりません。これによりほとんどのヌルチェックは不要になりますが、エラーを診断するのがずっと難しくなります。
  • Nice潜在的にヌルバージョンと非NULLバージョン:、Javaの由来言語、すべてのタイプの2つのバージョンがあります。not-null型でのみメソッドを呼び出すことができます。潜在的にnullの型は、nullを明示的に検査することによって、非null型に変換できます。これにより、ヌルチェックが必要な場所とそうでない場所を簡単に知ることができます。



その質問には、エラー処理戦略に興味があるかもしれないことを指摘してください。チームの設計者は、エラーの処理方法を決定する必要があります。これを行うにはいくつかの方法があります:

  1. 例外を波及させる - 「メインループ」または他の管理ルーチンでそれらを捕まえます。

    • エラー状態をチェックし、適切に処理する

もちろん、Aspect Oriented Programmingもありif( o == null ) handleNull()ます。バイトコードに挿入するためのきれいな方法があります。




nullを使用しないでください。それを許さないでください。

私のクラスでは、ほとんどのフィールドとローカル変数にはnull以外のデフォルト値があります。また、コード内のどこにでもコントラクトステートメント(always-on asserts)を追加して、これが強制されていることを確認します(より簡潔で、 NPEとして出て行番号などを解決する必要があります)。

私がこの練習を採用すると、問題は自分自身で解決するように見えました。開発プロセスの偶然ではなく、開発プロセスの早い段階で物事を捉えて、あなたには弱点があることを理解しています。もっと重要なのは、モジュールの懸念をカプセル化し、モジュールが互いに信頼でき、if = null else構造を持つコード!

これは防御的なプログラミングであり、長期的にはよりクリーンなコードになります。厳しい基準を適用するなどして、データを常に浄化してください。問題は解決します。

class C {
    private final MyType mustBeSet;
    public C(MyType mything) {
       mustBeSet=Contract.notNull(mything);
    }
   private String name = "<unknown>";
   public void setName(String s) {
      name = Contract.notNull(s);
   }
}


class Contract {
    public static <T> T notNull(T t) { if (t == null) { throw new ContractException("argument must be non-null"); return t; }
}

契約は、生産中であっても常に稼動しているミニユニットテストのようなもので、何かが失敗した場合、何らかの理由でNPEが無作為に抽出されるのではなく、その理由が分かります。




これはすべてのJava開発者にとって非常に一般的な問題です。したがって、コードが混乱することなくこれらの問題に対処するために、Java 8に正式なサポートがあります。

Java 8が導入されましたjava.util.Optional<T>。これは、null以外の値を保持する場合と保持しない場合があるコンテナです。Java 8では、いくつかのケースで値がnullになる可能性のあるオブジェクトをより安全に処理する方法が提供されています。HaskellScalaアイデアからインスパイアされています。

簡単に言えば、Optionalクラスには、値が存在する場合と存在しない場合を明示的に処理するメソッドが含まれています。ただし、null参照と比較した場合の利点は、省略可能な<T>クラスでは、値が存在しない場合を考慮する必要があることです。結果として、意図しないヌルポインター例外を防ぐことができます。

上記の例では、自宅で利用可能な複数のアプライアンスへのハンドルを返すホームサービスファクトリがあります。しかし、これらのサービスは利用可能/機能していない場合があります。つまり、NullPointerExceptionが発生する可能性があります。ifサービスを使用する前にnull 条件を追加するのではなく、オプション<Service>にラップしてみましょう。

ラッピングするオプション<T>

ファクトリからサービスの参照を取得する方法について考えてみましょう。サービス参照を返す代わりに、オプションでラップしてください。APIユーザーは、返されたサービスが使用可能か機能していないか、防御的に使用されているかどうかを知ることができます

public Optional<Service> getRefrigertorControl() {
      Service s = new  RefrigeratorService();
       //...
      return Optional.ofNullable(s);
   }

あなたが見るOptional.ofNullable()ように、参照をラップさせる簡単な方法を提供します。オプションの参照を取得する別の方法は、Optional.empty()&のどちらかOptional.of()です。ヌルをリターンするのではなく空のオブジェクトを返すためのものと、ヌル可能でないオブジェクトをラップするもう一つのもの。

だから、正確にそれがNULLチェックを回避するのに役立ちますか?

参照オブジェクトをラップしたら、オプションは、NPEなしでラップされた参照のメソッドを呼び出すための多くの便利なメソッドを提供します。

Optional ref = homeServices.getRefrigertorControl();
ref.ifPresent(HomeServices::switchItOn);

Optional.ifPresentは、nullでない値の場合、指定されたConsumerを参照付きで呼び出します。それ以外の場合は、何もしません。

@FunctionalInterface
public interface Consumer<T>

単一の入力引数を受け取り、結果を返さない操作を表します。ほとんどの他の機能的なインターフェースとは異なり、コンシューマーは副作用を介して動作することが期待されています。とてもきれいで理解しやすいです。上記のコード例でHomeService.switchOn(Service)は、オプションの保持参照がnull以外の場合に呼び出されます。

ヌル状態をチェックし、代替値またはデフォルト値を返すために、3項演算子を非常に頻繁に使用します。オプションは、nullをチェックせずに同じ条件を処理する別の方法を提供します。Optional.orElse(defaultObj)は、Optionalがnull値を持つ場合はdefaultObjを返します。サンプルコードでこれを使用しましょう:

public static Optional<HomeServices> get() {
    service = Optional.of(service.orElse(new HomeServices()));
    return service;
}

今HomeServices.get()は同じことをしますが、より良い方法で行います。サービスが既に初期化されていないかどうかをチェックします。そうであれば、それを返すか、新しい新しいサービスを作成します。オプションの<T>。orElse(T)はデフォルト値を返すのに役立ちます。

最後に、NPEとヌルチェックフリーのコードを示します:

import java.util.Optional;
public class HomeServices {
    private static final int NOW = 0;
    private static Optional<HomeServices> service;

public static Optional<HomeServices> get() {
    service = Optional.of(service.orElse(new HomeServices()));
    return service;
}

public Optional<Service> getRefrigertorControl() {
    Service s = new  RefrigeratorService();
    //...
    return Optional.ofNullable(s);
}

public static void main(String[] args) {
    /* Get Home Services handle */
    Optional<HomeServices> homeServices = HomeServices.get();
    if(homeServices != null) {
        Optional<Service> refrigertorControl = homeServices.get().getRefrigertorControl();
        refrigertorControl.ifPresent(HomeServices::switchItOn);
    }
}

public static void switchItOn(Service s){
         //...
    }
}

完全な投稿は、NPEとNullチェックフリーのコードです...本当ですか?




私は試しましたNullObjectPatternが、私にとっては常に最善の方法ではありません。「行動なし」が適切でない場合があります。

NullPointerException開発者の間違いを意味する実行時例外です。十分な経験があれば、どこにエラーがあるのか​​が正確に伝えられます。

今答えに:

すべての属性とアクセサをできるだけ非公開にするか、まったくクライアントに公開しないようにしてください。もちろんコンストラクタで引数の値を持つことはできますが、スコープを減らすことで、クライアントクラスが無効な値を渡すことはありません。値を変更する必要がある場合は、いつでも新しい値を作成できますobject。コンストラクタの値は一度だけチェックし、残りのメソッドでは値がnullではないことをほぼ確実に確認できます。

もちろん、この提案を理解して適用するには経験がより良い方法です。

バイト!




もっと一般的に答えてもいいですか?

私たちは、通常の方法は、我々が期待していない方法でパラメータを取得するとき、この問題に直面している(悪いメソッド呼び出しは、プログラマのせいです)。たとえば、オブジェクトを取得すると予想されますが、代わりにnullが返されます。少なくとも1つの文字を含むStringを取得することを期待していますが、代わりに空のStringを取得します。

だから違いはありません:

if(object == null){
   //you called my method badly!

}

または

if(str.length() == 0){
   //you called my method badly again!
}

彼らは、他の機能を実行する前に、両方が有効なパラメータを受け取っていることを確認する必要があります。

他のいくつかの答えで述べたように、上記の問題を避けるためには、Design by contractのパターンに従うことができます。http://en.wikipedia.org/wiki/Design_by_contractご覧ください。

このパターンをjavaで実装するには、javax.annotation.NotNullなどのコアJavaアノテーションを使用するか、Hibernate Validatorのような高度なライブラリを使用します。

ちょうどサンプル:

getCustomerAccounts(@NotEmpty String customerId,@Size(min = 1) String accountType)

これで、入力パラメータをチェックする必要なく、安全にメソッドのコア機能を開発でき、予期しないパラメータからメソッドを保護できます。

さらに一歩進んで、アプリケーションで有効なポーズだけを作成できることを確認してください。(hibernateバリデータサイトのサンプル)

public class Car {

   @NotNull
   private String manufacturer;

   @NotNull
   @Size(min = 2, max = 14)
   private String licensePlate;

   @Min(2)
   private int seatCount;

   // ...
}



  1. 変数をnullに初期化しないでください。
  2. (1)が不可能な場合は、すべてのコレクションと配列を空のコレクション/配列に初期化します。

あなた自身のコードでこれを行うと、あなたは避けることができます!=ヌルチェック。

ほとんどの場合、ヌルチェックはコレクションや配列に対してループを守るように見えるので、空にするだけでヌルチェックは必要ありません。

// Bad
ArrayList<String> lemmings;
String[] names;

void checkLemmings() {
    if (lemmings != null) for(lemming: lemmings) {
        // do something
    }
}



// Good
ArrayList<String> lemmings = new ArrayList<String>();
String[] names = {};

void checkLemmings() {
    for(lemming: lemmings) {
        // do something
    }
}

これにはわずかなオーバーヘッドがありますが、コードがより洗練され、NullPointerExceptionsが少ないほど価値があります。




public static <T> T ifNull(T toCheck, T ifNull) {
    if (toCheck == null) {
           return ifNull;
    }
    return toCheck;
}



Related