空指针异常是java永远的痛
package com.test.com.java.utils;
/**
* Created by jingwen on 19/4/13.
*/
public class Tools {
/**
*
* @param type 0,1,2
* @return
*/
public static String getCarNameByType(int type){
String name = null;
switch (type){
case 0:
name = "宾利";
break;
case 1:
name = "比亚迪";
break;
case 2:
name = "北汽";
break;
}
return name;
}
}
//主程序
package com.test.com.java.utils;
/**
* Created by jingwen on 19/4/13.
*/
public class TestMain {
public static void main(String[] args){
System.out.println();
String carName = Tools.getCarNameByType(9);
System.out.println(carName);
System.out.println(carName.length());
}
}
控制台输出:
Exception in thread "main" java.lang.NullPointerException
null
at com.test.com.java.utils.TestMain.main(TestMain.java:11)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Process finished with exit code 1
kotlin 非常牛B的解决了NullPointerException
在kotlin中不允许你赋值为空.
package com.base
/**
* Created by jingwen on 19/4/13.
*/
fun getCarNameByType( type:Int)
: String {
return "宾利"
}
fun main(args: Array) {
var carName:String = getCarNameByType(1)
println(carName)
}
如果需要返回为空值需要在函数类型后面加?,使用的所有地方都要加?
package com.base
/**
* Created by jingwen on 19/4/13.
*/
fun getCarNameByType(): String? {
return null
}
fun main(args: Array) {
var carName:String? = getCarNameByType()
println(carName?.length)
}
输出结果:
null
Process finished with exit code 0
明知道字符串不为空,可以使用!!来告诉编译器
package com.base
/**
* Created by jingwen on 19/4/13.
*/
fun getCarNameByType(): String? {
return null
}
fun main(args: Array) {
var carName:String? = "jingwen";
println(carName!!.length)
}
运行结果:
7
Process finished with exit code 0
类型转换:
java代码
package com.test;
/**
* Created by jingwen on 19/4/13.
*/
class Parent {
}
/**
* Created by jingwen on 19/4/13.
*/
class Child extends Parent {
public void childSay(){
System.out.println("Child say hello world");
}
}
/**
* Created by jingwen on 19/4/13.
*/
public class TestCast {
public static void main(String[] args){
Parent o = new Child();
((Child)o).childSay();
if (o instanceof Child){
((Child) o).childSay();//明明知道是Child对象,就不应该强转了,java太傻了,kotlin就比较聪明
}
}
}
package com.base
/**
* Created by jingwen on 19/4/13.
*/
open class Parent{
}
class Child :Parent(){
init {
}
fun childsay():Unit{
println("child say hello world")
}
}
fun main(args: Array) {
var p:Parent = Child()
if(p is Child){
p.childsay()//kotlin是不是很牛逼哈
}
//类型转换
var c = p as Child
c.childsay()
}
安全的类型转换:
kotlin也是有脾气的也会出现类型转换异常
package com.base
/**
* Created by jingwen on 19/4/13.
*/
open class Parent{
}
class Child :Parent(){
init {
}
fun childsay():Unit{
println("child say hello world")
}
}
fun main(args: Array) {
// var p:Parent = Child()
// if(p is Child){
// p.childsay()
// }
//
// //类型转换
// var c = p as Child
// c.childsay()
var p:Parent = Parent()
var c:Child = p as Child
c.childsay()
}
输出结果:
Exception in thread "main" java.lang.ClassCastException: com.base.Parent cannot be cast to com.base.Child
at com.base.TestcastKt.main(testcast.kt:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Process finished with exit code 1
你不让我类型你也别让我出现ClassCastException啊
解决方案: as?
package com.base
/**
* Created by jingwen on 19/4/13.
*/
open class Parent{
}
class Child :Parent(){
init {
}
fun childsay():Unit{
println("child say hello world")
}
}
fun main(args: Array) {
// var p:Parent = Child()
// if(p is Child){
// p.childsay()
// }
//
// //类型转换
// var c = p as Child
// c.childsay()
var p:Parent = Parent()
var c:Child? = p as? Child
if (c != null) {
c.childsay()
} else{
println("c=="+c)
}
}
c==null
Process finished with exit code 0
总结:
val notNull:String = null//编译错误,规定不能为空
val nullable:String? = null//编译正确,?可能为空
notNull.length //编译正确,不为空的值可以直接使用
nullable.length//编译错误,可能为空的值,不能直接使用length方法.会出现NullPointerException
nullable?.length//编译正确, 如果为空,这个表达式的值为空
nullable!!.length//编译正确,可以骗过编译器
val str:String?=null
println(str!!.length)
照样程序崩溃:
Exception in thread "main" kotlin.KotlinNullPointerException
at com.base.TestcastKt.main(testcast.kt:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
java Style类型转换
val sub:SubClass = parent as SubClass
类似于java转换失败就会报异常
安全的类型转换
val sub:SubClass? = parent as? SubClass
程序不会崩溃
sub 转换失败后,sub这个对象是空值.
智能类型转换
if( parent is SubClass){
parent.childSay()//编译器智能推导出是SubClas的对象, 智能转换了
}
if(parent != null){
parent.childSay()//跟java一样 ,可以大胆调用不会出现空指针
}