java中var
【CSDN 编者按】Kotlin 和 Java 是如何解决 Null 问题?本文作者分享了解决思路。
原文链接:https://blog.frankel.ch/null-safety-java-vs-kotlin/
未经授权,禁止转载!
作者 | Nicolas Fränkel 责编 | 弯月出品 | CSDN(ID:CSDNnews)在本文中,我想讨论一下 Kotlin 和 Java 是如何解决 Null 问题的。
可为 Null
相信每一位从事软件开发超过两年的人都听过下面这句话:
我把 Null 引用称为自己的十亿美元错误。它的发明是在 1965 年,那时我用一个面向对象语言(ALGOL W)设计了第一个全面的引用类型系统。我的目的是确保所有引用的使用都是绝对安全的,编译器会自动进行检查。但是我未能抵御住诱惑,加入了 Null 引用,仅仅是因为实现起来非常容易。结果导致了数不清的错误、漏洞和系统崩溃,可能在之后的 40 年中造成了十亿美元的损失。
—— 图灵奖得主 Tony Hoare
Null 背后的基本思想是能够定义一个未初始化的变量。当有人调用这类变量的某个成员时,运行时就会寻找变量的内存地址,结果就是引用失败,因为其后面没有任何东西。
许多编程语言都包含 Null 值,只不过名称不同罢了:
Python 有 None;
JavaScript 有 null;
Java、Scala 和 Kotlin 也有 null;
Ruby 有 nil;
以及其他等等。
有些不允许使用未初始化的值,比如 Rust。
Kotlin 中的 Null 安全性如上所示,Kotlin 也有 null 值。只不过,null 融入到了类型系统中。在 Kotlin 中,每个类型 X 实际上都有两种类型:
X:不可为 null,类型 X 的任何变量都不可以为 null。编译器会确保这一点;
val str: String = null上述代码无法通过编译。
X?:可以为 null。
val str: String? = null上述代码可以编译。
既然 Kotlin 允许使用 null 值,为什么支持者们会鼓吹它具有 null 安全性呢?因为编译器会调用可能为 null 值(即可为空类型)的成员。
val str: String? = getNullableString()val int: Int? = str.toIntOrNull() #1#1 无法通过编译。
修复上述代码的方式是,在调用成员之前,先检查变量是否为 null:
val str: String? = getNullableString()val int: Int? = if (str == null) null else str.toIntOrNull()这种方法很模式化,Kotlin 提供了 null 安全的运算符:
val str: String? = getNullableString()val int: Int? = str?.toIntOrNull()Java 中的 Null 安全性如上,我们讨论了 Kotlin 管理 Null 值的方法,下面我们来看看 Java。
首先,Java 中既没有不可为 null 的类型,也没有 null 安全的运算符。因此,每个变量都有可能为 null,而且我们也的确应该如此思考。
MyString str = getMyString(); #1 Integer anInt = null; #2if (str != null) { anInt = str.toIntOrNull();}#1 String 没有 toIntOrNull() 方法,所以我们假设 MyString 是一个包装类型,实际的操作交给 String。
#2 这里必须使用可变引用。
如果将多个调用放在一起,结果更糟,因为每个返回值都有可能为 null。为了安全着想,我们需要检查每个方法调用返回的值是否为 null。如下代码片段有可能抛出异常 NullPointerException:
var baz = getFoo().getBar().getBaz();修复方法如下,但非常繁琐:
var foo = getFoo();var bar = null;var baz = null;if (foo != null) { bar = foo.getBar(); if (bar != null) { baz = bar.getBaz(); }}出于这个原因,Java 8 引入了 Optional 类型。Optional 是一个包装,负责处理可能为 null 值的情况。在其他语言中,该类型被称为 Maybe、Option 等。
Java 语言的设计者建议,方法应返回:
如果 X 不可能为 null,则返回类型 X;
如果 X 可能为 null,则返回类型 Optional。
如果我们将上述方法的返回类型改为 Optional,就可以编写出 null 安全的代码,而且还可以获得不可变性:
final var baz = getFoo().flatMap(Foo::getBar) .flatMap(Bar::getBaz) .orElse(null);对于这种方法,我认为核心问题在于,Optional 本身可以为 null。Java 语言本身无法确保 Optional 不为 null。此外,方法的输入参数不建议使用 Optional。
为了解决这个问题,网上涌现了很多基于注解的库:
然而,不同的库,处理方式也不同:
Spring 会在编译时生成警告消息;
FindBugs 需要专门执行;
Lombok 会生成一段检查 null 的代码,如果变量无论如何都会为 null,则抛出异常 NullPointerException。
总结当 Null 安全性不是一个大问题时,Java 可以被接受。因此,NullPointerException 异常会频繁发生。唯一安全的解决方案是将每个方法调用包装在 null 检查中。这种方式很有效,但同时也很模式化,代码也更加难以阅读。开发人员称赞 Kotlin 带来了 Null 安全性,这是因为该语言的设计中融入了 Null 值处理机制。Java 这方面的处理远不如 Kotlin,因为 Java 语言架构师更加重视向后兼容性,而不是代码安全,这是设计上的决定。但是,作为一名开发人员,从 Null 安全性的角度出发,我认为 Kotlin 是比 Java 更有吸引力的选择。
宰废彬2538javascript中,var和java中的String一模一样吗? -
颜瑶窦17258425833 ______ javascript中变量是弱类型,也就是说你给她赋什么值她就是什么,举个例子:var str = "abc",此时str就是字符串类型, 如果写var str = 3,那么str就是number类型,就是这么个意思.
宰废彬2538java operator中 ++var - - var var++ var--什么意思
颜瑶窦17258425833 ______ ++ -- 在变量的前面就是先加减再用 如果++ -- 在变量后面就是用完之后 再加减
宰废彬2538我已经升级java10了 为什么var 报错 -
颜瑶窦17258425833 ______ 你使用什么编译的,是原始javac命令还是Eclipse,是javac中报错还是Eclipse中红叉报错
宰废彬2538v a,var,varh 是什么意思 -
颜瑶窦17258425833 ______ var定义变量!如varaa=1;varbb="字符串";说的简单一点点就是定义一个变量.在java-script中,变量可以用命令Var作声明:比如VARmytestvarmytest='thisisabook"就是自定义变量的保留字啊
宰废彬2538页面中嵌的java代码中如何获取到js方法中的var变量 -
颜瑶窦17258425833 ______ 直接取值是做不到的,下面有具体分析 http://bbs.csdn.net/topics/360054659
宰废彬2538java中String的replaceAll方法 -
颜瑶窦17258425833 ______ 字符组中“\”是有转义的含义的,就跟你replaceAll中使用多个"\"是为了转义一样.你定义var1时,java是认为"dfas\'f"中的"\"是转义字符,转义"'"(最后还是"'").所以var1和var2其实是一样的.这也是为什么你replaceAll后的结果...
宰废彬2538js中,var修饰变量名,它可有可无吗?
颜瑶窦17258425833 ______ 关于这个问题,不是可以可无的,var其实就和java的String差不多,但是可以重复修饰一个变量,在函数外面就是全局变量,函数里面是局部变量.如果自己随便定义一个变量,又没有var修饰会报异常额
宰废彬2538(HTML)任何javascript语句里面必须有变量var吗? -
颜瑶窦17258425833 ______ 不是必须的,var是一个弱变量类型,具体的类型是根据其赋值来看的,比如var a=33.5;var b="aaaaa";a的类型为double,b的类型为string,当然这两句中var都可...
宰废彬2538JS中var abc = new Number(68);与var abc = 68;有什么本质上的区别吗? -
颜瑶窦17258425833 ______ 本质区别就是:类型不同 前者是返回的是一个object,后者返回一个number. typeof new Number(6); //object typeof 68; //number
宰废彬2538在jsp页面中java代码获取js里面var变量的值 -
颜瑶窦17258425833 ______ jsp页面中在java语句里面要想获取js的变量的值,你可以试试使用request对象