Java 在';是';类型检查

Java 在';是';类型检查,java,kotlin,Java,Kotlin,根据的文档,它可以替换“if-else-if”,因此我尝试实现一个函数,最多返回两个Any类型的变量: fun maxOf(a: Any, b: Any) = when { a is Int && b is Int -> if (a < b) b else a a is Double && b is Double -> if (a < b) b else a a is Int && b

根据的文档,它可以替换“if-else-if”,因此我尝试实现一个函数,最多返回两个
Any
类型的变量:

fun maxOf(a: Any, b: Any) = when {
    a is Int && b is Int        -> if (a < b) b else a
    a is Double && b is Double  -> if (a < b) b else a
    a is Int && b is Double     -> if (a < b) b else a
    a is Double && b is Int     -> if (a < b) b else a
    a is String && b is String  -> if (a < b) b else a
    else                        -> null
}
为什么会这样? 这不是表达时的问题。你应该归咎于类型系统


a
b
Int
Double
的实例,因此Kotlin将推断它们为LCA。例如:

open class A { fun a() = println("meow meow meow") }
class B : A()
class C : A()
if (a is B || a is C) a.a() // smart cast works

但是,
Int
Double
同时是
Number
Comparable
的子类,Kotlin不知道您想要的是
Number
还是
Comparable
,因此Kotlin将其视为
Any
的实例

if (a is Int || a is Double)
  if (a > 1) print("meow meow") // smart cast doesn't work
这就是“bug”出现的原因

如何解决这个问题? 使用您的原始代码,或者使用显式转换(我知道它很糟糕,但它确实是一个不可避免的问题)

我想出了一个漂亮的解决办法!看看它:

fun <T : Comparable<T>> maxOf(a: T, b: T): T? = when {
    (a is Int || a is Double) && (b is Int || b is Double) -> if (a < b) b else a
    a is String && b is String -> if (a < b) b else a
    else -> null
}
如果输入无效,原始版本将返回
null
,如果输入无效,此版本将引发编译错误,帮助您在编译时查找错误

提到! 你对我发表了评论,并问了一个进一步的问题。我想让我的回答更具可读性,所以我会将其添加到我的答案中

fun someFunction(a: Number) {
    if (a is Int || a is Double) println(a < 1) // still error! Why?!
}
你说:

如果
a
b
的类型为
Any

  • 解决方案零:创建
    运算符fun Any.compareTo
  • 解决方案一:放弃铸造

Int
Double
数字
可比
的子类……Kotlin将其视为
任何
的一个实例”,您在回答中提到。但是,如果我强制a
a
成为一个
Number
,以下仍然不起作用:
funprintmeow(a:Number){if(a是Int | | a是Double)if(a>1)print(“meow”)}
,所以我不太确定这是不是真的。编辑并回答了你的问题。嘿!我刚刚想出了一个非常漂亮的解决方案,请看一看!我现在觉得自己非常聪明:至少smart cast足够聪明,可以知道类型
T
T
相同,并进行比较。这不是smart cast的工作。这是泛型。你为什么不使用Comparable?@njzk2你能更具体一点吗?nvm,这不适用于比较整数和双倍数
fun <T : Comparable<T>> maxOf(a: T, b: T): T? = when {
    (a is Int || a is Double) && (b is Int || b is Double) -> if (a < b) b else a
    a is String && b is String -> if (a < b) b else a
    else -> null
}
fun <T : Comparable<T>> maxOf(a: T, b: T): T = if (a < b) b else a
fun someFunction(a: Number) {
    if (a is Int || a is Double) println(a < 1) // still error! Why?!
}
fun <A : Comparable<B>, B : Any> maxOf(a: A, b: B): Any = if (a < b) b else a