最近在处理一个需求,需求描述如下:对数据库中查询出来的数据的某一个字段做一个简单处理。处理方式是:如果该字段的值(取值范围0~4,有可能为null)等于0,那么默认处理成1。

测试代码如下:

 public class TestNull {

     private Integer starLevel;

     public Integer getStarLevel() {
return starLevel;
} public void setStarLevel(Integer starLevel) {
this.starLevel = starLevel;
} public static void main(String[] args) {
TestNull test = new TestNull(); Integer localStartLevel =
test.getStarLevel() != null && test.getStarLevel() == 0 ? 1 : test.getStarLevel(); System.out.println(localStartLevel);
} }

因为不想写if-else,所以直接使用了三目运算符,原因嘛肯定是方便、简洁呀。一切都大功告成了,感觉自己棒棒哒!!!然后开始自测(发现代码没什么问题的童鞋不妨copy一下上面的代码执行一下),报错了!!!空!指!针!

老实说,当时我撸这段代码很自信,我调试这段代码也看了三遍才找到原因。如果你也没找到原因,你可以把那个1换成Integer.valueOf(1)或者将分号后面的test.getStarLevel()

直接换成null(当然这样是不符合需求的)再试试。

问题原因:可能你也发现问题所在了,就是因为那个“方便、简洁”的三目运算符表达式

分析原因:

1、test.getStarLevel() != null && test.getStarLevel() == 0 ? 1 : test.getStarLevel()

结论:错误!因为有个分支是返回基本类型数值1,另一个分支返回的直接是对象的调用值(该值的类型在运行时动态确定的),所以,三目运算符帮我们统一处理成了基本类型装箱操作。所以null装箱肯定空指针。

2、test.getStarLevel() != null && test.getStarLevel() == 0 ? Integer.valueOf(1) : test.getStarLevel();

结论:正确!因为基本类型1已经被初始化为Integer对象了,然后这个赋值表达式都是直接赋值引用了,所以不会存在问题。

3、test.getStarLevel() != null && test.getStarLevel() == 0 ? 1 : null

结论:正确!该段跟第一段代码的唯一区别就是test.getStarLevel()换成了null,这就消灭了运行时动态确定该分支的返回值类型的不确定性,所以能够正确执行。

三目运算符固然是好用,但是使用时还是需要注意返回值类型的统一性呀!且用且珍惜!

该博客仅代表个人观点,如有不足之处,请不吝惜指教!!!

Thanks!!!




Java 三目运算符表达式的一些问题的更多相关文章

  1. Java Lambda表达式初探

    Java Lambda表达式初探 前言 本文受启发于Trisha Gee在JavaOne 2016的主题演讲Refactoring to Java 8. Java 8已经发行两年多,但很多人仍然在使用 ...

  2. Java Lambda表达式入门

    Java Lambda表达式入门 http://blog.csdn.net/renfufei/article/details/24600507 Java 8十个lambda表达式案例 http://w ...

  3. Java Web表达式注入

    原文:http://netsecurity.51cto.com/art/201407/444548.htm 0×00 引言 在2014年6月18日@终极修炼师曾发布这样一条微博: 链接的内容是一个名为 ...

  4. 利用Java实现表达式二叉树

    (*^-^*) 什么是二叉树,这里不再介绍,可以自行百度:二叉树.在这里利用java实现“表达式二叉树”. 表达式二叉树的定义 第一步先要搞懂表达式二叉树是个什么东东?举个栗子,表达式:(a+b×(c ...

  5. Java Lambda表达式入门[转]

    原文链接: Start Using Java Lambda Expressions http://blog.csdn.net/renfufei/article/details/24600507 下载示 ...

  6. ref:一种新的攻击方法——Java Web表达式注入

    ref:https://blog.csdn.net/kk_gods/article/details/51840683 一种新的攻击方法——Java Web表达式注入 2016年07月06日 17:01 ...

  7. Java Lambda表达式教程与示例

    Lambda表达式是Java 8中引入的一个新特性.一个lambda表达式是一个匿名函数,而且这个函数没有名称且不属于任何类.lambda表达式的概念最初是在LISP编程语言中引入的. Java La ...

  8. Java Lambda表达式forEach无法跳出循环的解决思路

    Java Lambda表达式forEach无法跳出循环的解决思路 如果你使用过forEach方法来遍历集合,你会发现在lambda表达式中的return并不会终止循环,这是由于lambda的底层实现导 ...

  9. Java描述表达式求值的两种解法:双栈结构和二叉树

    Java描述表达式求值的两种解法:双栈结构和二叉树 原题大意:表达式求值 求一个非负整数四则混合运算且含嵌套括号表达式的值.如: # 输入: 1+2*(6/2)-4 # 输出: 3.0 数据保证: 保 ...

随机推荐

  1. [编织消息框架][netty源码分析]4 eventLoop 实现类NioEventLoop职责与实现

    NioEventLoop 是jdk nio多路处理实现同修复jdk nio的bug 1.NioEventLoop继承SingleThreadEventLoop 重用单线程处理 2.NioEventLo ...

  2. Go - method

    hello, 大家好,由于之前工作上面的事情较多,所以关于go语言的学习就暂时“搁浅了”...不过从今天开始,我们又将回到了go语言的学习过程之中. 当然,我们学习go的"初心"是 ...

  3. Linux 程序,进程和线程

    进程如何使用内存. 当程序文件运行为进程时, 进程在内存中获得空间. 1) Text : 固定大小 存储指令(instruction), 说明每一步的操作. 2) Global Data : 固定大小 ...

  4. php中curl远程调用获取数据

    $jump_url=$this->_post('locations'); $url=htmlspecialchars_decode($jump_url); $ch = curl_init(); ...

  5. AngularJS-repeat指令

    <body ng-app="myApp"> <div ng-controller="myCtrl"> <ul> <li ...

  6. laravel怎么创建一个简单的blog

    主要功能实现:点击标题跳转 第一步:创建路由: Route::get('/articles','ArticlesController@index'); Route::get('/articles/{i ...

  7. bootstrap图标字体不出来问题的解决办法

    @font-face { font-family: 'Glyphicons Halflings'; src: url('/Scripts/bootstrap/fonts/glyphicons-half ...

  8. 关于jquery全选反选 批量删除的一点心得

    废话不多说直接上代码: 下面是jsp页面的html代码: <table id="contentTable" class=""> <thead& ...

  9. 以芯片直读方式得到的全盘镜像解析及ext4日志区域解析

    之前在centos中分析了/dev/sda1下的结构,但当对象是一块以芯片直读方式作出来的全盘镜像呢? 这次以安卓手机的全盘镜像为对象,尝试按照ext4文件系统结构手动解析,加强对ext4文件系统.E ...

  10. XManager与SecureCRT

    使用Xmanager前,服务器必须已经安装好X11所需的各种运行包.运行下列命名检查安装情况,没有的话请自行补上. rpm -qa|grep x11 1.DISPLAY环境变量 export DISP ...