6

Scala コンパイラには-Xcheck-null、実行時に null ポインターの逆参照の可能性があるかどうかをチェックしようとするものがあります。

私には問題ありませんが、誤検知が多すぎます。つまり、 logger を定義するとします。

private final val LOGGER: Logger = LoggerFactory.getLogger(classOf[GenericRestImpl])

メソッドgetLoggerは を返しませんnull。この知識をコンパイラに渡して文句を言わないようにするにはどうすればよいですか?

[WARNING] TestImpl.scala:31: warning: potential null pointer dereference: LOGGER.debug
[WARNING]       LOGGER.debug("Using {} for sort", sortParam)

新しいインスタンスを作成するときに、NotNull特性でマークできます。

return new Foo() with NotNull.

それは問題ありませんが、他のメソッドから返されたオブジェクトをどうするのでしょうか? 特にサードパーティのライブラリから来ている場合は? オーバーヘッドが大きくなりすぎるため、すべての変数をオプションとしてマークするのは好きではありません。また、暗黙的な変換を作成するという考えは好きではありません (NotNull としてマークするクラスごとに追加のクラスが必要になるため)。

また、Scala の NotNull 特性に対する質問ライブラリのサポートも確認しましたが、問題の解決には役立ちませんでした。

4

1 に答える 1

5

Jatinが言及しているように、NotNullは単なるマーカーまたはタグであるため、NotNull何でもタグ付けできます。これを行う秘訣は、基本型を強制的にキャストすることwith NotNullです。

したがって、このようなものを書くことができます"notnull".asInstanceOf[String with NotNull]。null になることがないことが確実な場合は、安全なキャストです。

したがって、実際の例では、次のように書くことができます。

private final val LOGGER: Logger with NotNull = 
   LoggerFactory.getLogger(classOf[GenericRestImpl]).asInstanceOf[Logger with NotNull]

このために新しい型を作成する必要はありませんが、何度も行う必要がある場合は少し面倒なので、いくつかの小さなユーティリティを使用して表記を簡素化/明確化できます。

type NeverNull[T] = T with NotNull
def neverNull[A](a: A): NeverNull[A] = a.asInstanceOf[A with NotNull]

NeverNullTでタグ付けされた任意の型の単なるエイリアスであり、型の既存の値をnull ではないNotNullというneverNullタグを付けるための小さなラッパーです。A

その後、次のように使用できます。

private final val LOGGER: NeverNull[Logger] = neverNull {
       LoggerFactory.getLogger(classOf[GenericRestImpl])
}

何をしているのか本当に確信がある場合は、これを暗黙の変換にすることもできます。

implicit def neverNull[A](a: A): NeverNull[A] = a.asInstanceOf[A with NotNull]

private final val LOGGER: NeverNull[Logger] = LoggerFactory.getLogger(classOf[GenericRestImpl])

NeverNull[Logger]はまだ であるLoggerため、そのクラスの任意のメソッドを呼び出すか、パラメーターとして a を取る関数に渡すことができますLogger

この種のコンストラクトは、ボックス化されていないタグ付きタイプと呼ばれ、非常に便利です。他のアプリケーションと議論を参照してくださいここここ.

于 2013-09-04T02:33:16.797 に答える