代码之家  ›  专栏  ›  技术社区  ›  Kalle Richter

如何在Kotlin中检查列表是否包含null?

  •  3
  • Kalle Richter  · 技术社区  · 6 年前

    我不明白为什么

    class Main {
        private val outputStreams: List<OutputStream>
    
        @JvmOverloads constructor(outputStreams: List<OutputStream> = LinkedList()) {
            if(outputStreams.contains(null)) {
                throw IllegalArgumentException("outputStreams mustn't contain null")
            }
            this.outputStreams = outputStreams
        }
    }
    

    ...Main.kt:[12,26] Type inference failed. The value of the type parameter T should be mentioned in input types (argument types, receiver type or expected type). Try to specify it explicitly. .

    如果我使用 outputStreams.contains(null as OutputStream)) 编译成功,但是 Main(LinkedList<OutputStream>()) 运行时失败,原因是

    kotlin.TypeCastException: null cannot be cast to non-null type java.io.OutputStream
        at kotlinn.collection.contains.nulll.check.Main.<init>(Main.kt:12)
        at kotlinn.collection.contains.nulll.check.MainTest.testInit(MainTest.kt:13)
    

    4 回复  |  直到 6 年前
        1
  •  4
  •   s1m0nw1    6 年前

    对于编译器,参数 outputStreams 不能包含 null 因为它的类型是 List<OutputStream> 相对于 List<OutputStream?> . 类型系统不期望 无效的 在这张单子里,所以不需要检查。

    另一方面 , 这个参数实际上可以包含 无效的 (因为它来自Java调用者)您应该显式地将其标记为可空: 列表<输出流?>

        2
  •  3
  •   ToraCode    6 年前

    List<OutputStream?> . ? 将使你的名单可以包含 null 检查文档: enter link description here

        3
  •  1
  •   Pitos    6 年前

    显然,您需要通知编译器集合中的对象可以为null。

        class Main{
    private val outputStreams: List<String?>
    
    @JvmOverloads constructor(outputStreams: List<String?> = LinkedList()) {
    
        if(outputStreams.filterNotNull().size < outputStreams.size) {
            throw IllegalArgumentException("outputStreams mustn't contain null")
        }
        this.outputStreams = outputStreams
    }
    
    fun getOutputStream(): List<String?>{
        return outputStreams
    }
     }
    

    第二种方法是使用let T.let(block:(T)—>R) :R,您将接受可为null的对象,但随后必须检查是否存在任何“null”字符串并做出相应的反应。

        class Main{
    lateinit var outputStreams: List<String?>
    
    @JvmOverloads constructor(outputStreams: List<String?> = LinkedList()) {
    
        outputStreams.let {
            this.outputStreams = outputStreams
        }
    
    }
    
    fun getOutputStream(): List<String?>{
        return outputStreams
    }
    }
    
        fun main(args: Array<String>) {
    val outputStreamWithNull: List<String?> = listOf("alpha", "beta", null, "omega")
    val mainA = Main(outputStreamWithNull)
    
    
    mainA.getOutputStream().forEach {
        println(it)
    }
    
    }
    

    但是,列表集合上的可空检查必须由初始化主类的对象完成,因此您基本上将捕获NullPointerException的责任转移给其他人。