728x90
발단
assert 를 통한 로직 검증에서 조건이 틀렸음에도 검증되지 않고 Pass-Through 한 경우가 있어 정리합니다.
Assert 란 무엇인가?
var a = 1
var b = 2
assert(1 < a+b) // _Assertions object 를 통해 참조된 assert 를 사용
assert(a+b < 1) { "msg" }
- 영단어로써 의미는 `주장하다` 라는 뜻을 가지고 있습니다.
- 코드에서는 assert 로 묶은 조건이 옳음을 주장하다 정도로 볼 수 있을 거 같습니다.
_Assertions object
@file:kotlin.jvm.JvmMultifileClass
@file:kotlin.jvm.JvmName("PreconditionsKt")
package kotlin
@PublishedApi
internal object _Assertions {
@JvmField
@PublishedApi
internal val ENABLED: Boolean = javaClass.desiredAssertionStatus()
}
/**
* Throws an [AssertionError] if the [value] is false
* and runtime assertions have been enabled on the JVM using the *-ea* JVM option.
*/
@kotlin.internal.InlineOnly
public inline fun assert(value: Boolean) {
assert(value) { "Assertion failed" }
}
/**
* Throws an [AssertionError] calculated by [lazyMessage] if the [value] is false
* and runtime assertions have been enabled on the JVM using the *-ea* JVM option.
*/
@kotlin.internal.InlineOnly
public inline fun assert(value: Boolean, lazyMessage: () -> Any) {
if (_Assertions.ENABLED) {
if (!value) {
val message = lazyMessage()
throw AssertionError(message)
}
}
}
- 위에서 알 수 있듯 assert 는 함수로 오버로딩을 통해 두가지 사용방식을 제공합니다.
왜 assert 가 동작하지 않았던 걸까?
assert 는 _Assertions.ENABLED 라는 bool 값에 따라 동작 여부가 결정되고, JVM 은 기본적으로 실행할 때 assert 옵션을 사용한다 명시하지 않기에 동작하지 않았던 것 입니다.
어떻게 assert 옵션을 사용할 수 있을까?(JVM 실행 변수)
// -ea(ENABLE ASSERTION) 를 작성하면 ENABLED 옵션이 세팅됩니다.
java -ea -jar YourApplication.jar
// 특정 클래스에 적용
java -ea:com.example.MyClass -jar YourApplication.jar
// 특정 패키지에 적용(`...`를 붙여야 합니다.)
java -ea:com.example... -jar YourApplication.jar
옵션과 무관한 처리(Kotlin)
inline fun customAssert(value: Boolean, lazyMessage: () -> String) {
if (!value) {
throw AssertionError(lazyMessage())
}
}
728x90