java中三步表达式,Java中三目运算符之类型转换

文章目录

1. 前言2. 三目运算符使用3. 类型转换3.1 尝试着分析一下

4. 结论与思考5. 源码参考

1. 前言

相信各位 Javaer 对于三目运算符(三元运算符)都不陌生,较多情况下使用三目运算符即可节省一个 if-else 语句赋值的编写,笔者也是经常使用三目运算符,前段时间遇到了一点三目运算符的类型转换的坑,便在此记录一下。望更多的朋友能够避免,也加深我对三目运算符的理解。

2. 三目运算符使用

闲话不说,直接上代码。

/**

* 三目运算符使用

*/

public void ternaryOperator() {

boolean switchLog = true;

// 基本类型

int intValue = switchLog ? 1 : 0;

// 引用类型

String strValue = switchLog ? "true" : "false";

}

三目运算符可表达为:布尔表达式 ? 表达式1 : 表达式2

布尔表达式:其结果决定三目运算符的分支情况 表达式1:当布尔表达式为 true,则执行 表达式2:当布尔表达式为 false,则执行

3. 类型转换

在三目运算符的使用过程中,即支持基本类型,也支持引用类型。值得注意的一点是,引用类型为 null 时,也是支持给引用类型赋值的。

特别的,我们关注到了基本类型和其封装类型,于是有了下述代码。

@Test

public void intInteger() {

boolean switchLog = true;

Integer oneExpre = null

Integer result = switchLog ? oneExpre : 0;

System.out.println(result);

}

猜想下这个程序的 result 返回什么,是 null 么?为什么?

试着运行下测试,发现得到以下报错:

java.lang.NullPointerException

at club.chenlinghong.demo.ternaryoperator.TernaryOperatorDemo.intInteger(TernaryOperatorDemo.java:28)

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:498)

at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)

at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)

at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)

at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)

at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)

at org.junit.runners.BlockJUnit4Cla***unner.runChild(BlockJUnit4Cla***unner.java:78)

at org.junit.runners.BlockJUnit4Cla***unner.runChild(BlockJUnit4Cla***unner.java:57)

at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)

at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)

at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)

at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)

at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)

at org.junit.runners.ParentRunner.run(ParentRunner.java:363)

at org.junit.runner.JUnitCore.run(JUnitCore.java:137)

at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)

at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)

at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)

at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70

NPE,有意思,命名没有任何问题呀,就算是 switchLog 为 true 嘛,也就把 null 值赋给 result 嘛,这不科学。

我们再来尝试下另外一种写法:

@Test

public void intInteger() {

boolean switchLog = true;

Integer oneExpre = null;

Integer result = switchLog ? oneExpre : new Integer(0);

System.out.println(result);

}

再次执行,居然没报错。result 为 null。

3.1 尝试着分析一下

报错的情况:

这种情况下,“表达式1” 结果是 null,而“ 表达式2 ” 是基本类型。大胆猜想一下,当执行时,先执行 “表达式1” 的得到返回结果 null ,此时 null 是一个特殊的值,并不知道其“具体的类型”,然后尝试着和 “表达式2” 进行统一类型,发现 “表达式2” 是 int 类型,并进行强转或者封装类型转基本类型,报NPE。

未报错的情况:

和报错情况不同的是,“表达式2”本身就是 Integer 类型,封装类型本身支持 null 类型赋值,便省去了类型强转的步骤,则不报错。

4. 结论与思考

这是一个有趣的实验,同时也是一个很坑的点。对于这些细枝末节的知识点(坑点),可能在平时学习和编码中都很少遇到,但是在遇到的时候,可能需要查很久很久的代码才能找到。

注重知识点的累计,多一次在学习中踩坑,就少一次在生产上的事故,哈哈哈哈哈 ~ _ ~

5. 源码

Github链接,欢迎star,follow。

demo-springboot

参考

关于三元运算符的类型转换问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值