5年前博客写的三目运算符空指针问题 ,终于被阿里开发手册收录了

5年前博客写的三目运算符空指针问题,终于被阿里开发手册收录了

作者 l Hollis 来源 l Hollis(ID:hollischuang)

最近,阿里巴巴Java开发手册发布了最新版 ,泰山版 ,这个名字起的不错,一览众山小 。

新版据说新增了30+规约,我还没来得及仔细去看 ,不过有粉丝和我说,其中新增的一条规约,他之前在我的博客中看到过。

仔细看了下 ,这个问题确实我很久之前遇到过,确实曾经在博客中也记录过。

5年前博客写的三目运算符空指针问题,终于被阿里开发手册收录了

最初遇到这个问题的是我的同事 ,他在代码中使用了三目运算符,代码在线上运行的时候发生了NPE,经过排查 ,发现原来是三目运算符和自动拆装箱之间有一定的关系,导致了空指针 。

这篇文章最开始发布于2015年,目前已经有1w+阅读量了 。

5年前博客写的三目运算符空指针问题	,终于被阿里开发手册收录了

趁着最新的开发手册中也提到了这个点 ,于是把之前的文章内容翻出来并重新整理了一下,带大家一起回顾下这个知识点。

一、三目运算符

对于条件表达式b?x:y,先计算条件b ,然后进行判断。如果b的值为true,计算x的值,运算结果为x的值;否则 ,计算y的值,运算结果为y的值 。一个条件表达式从不会既计算x,又计算y。条件运算符是右结合的 ,也就是说,从右向左分组计算。例如,a?b:c?d:e将按a?b:(c?d:e)执行 。

二 、自动装箱与自动拆箱

基本数据类型的 自动装箱 (autoboxing)、 拆箱 (unboxing)是自J2SE 5.0开始提供的功能。

一般我们要创建一个类的对象实例的时候 ,我们会这样:Class a = new Class(parameters);

当我们创建一个Integer对象时,却可以这样:Integer i = 100;( 注意:和 int i = 100;是有区别的 )

实际上,执行上面那句代码的时候 ,系统为我们执行了:Integer i = (100);

这里暂且不讨论这个原理是怎么实现的(何时拆箱、何时装箱) ,也略过普通数据类型和对象类型的区别。

我们可以理解为,当我们自己写的代码符合装(拆)箱规范的时候,编译器就会自动帮我们拆(装)箱 。

那么 ,这种不被程序员控制的自动拆(装)箱会不会存在什么问题呢?

三 、问题回顾

首先,通过你已有的经验看一下下面这段代码:

Map<String,Boolean>map=newHashMap<String,Boolean>();Booleanb=(map!=null?(test):false);

以上这段代码,是我们在不注意的情况下有可能经常会写的一类代码(在很多时候我们都爱使用三目运算符)。当然 ,这段代码是存在问题的,执行该代码,会报NPE.

Exception in thread main erException

首先可以明确的是 ,既然报了空指针,那么一定是有些地方调用了一个null的对象的某些方法。

在这短短的两行代码中,看上去只有一处方法调用(test) ,但是我们也都是知道,map已经事先初始化过了,不会是Null ,那么到底是哪里有空指针呢 。

我们接下来反编译一下该代码。看看我们写的代码在经过编译器处理之后变成了什么样。

反编译后代码如下:

HashMaphashmap=newHashMap();Booleanboolean1=(hashmap==null?false:((Boolean)(test)).booleanValue());

看完这段反编译之后的代码之后 ,经过分析我们大概可以知道问题出在哪里 。

((Boolean)(test)).booleanValue()的执行过程及结果如下:

(test)->null;

(Boolean)null->null;

lue()->报错

好,问题终于定位到了 。那么接下来看看如何解决该问题以及为什么会出现这种问题。

四 、原理分析

通过查看反编译之后的代码,我们准确的定位到了问题 ,分析之后我们可以得出这样的结论:NPE的原因应该是三目运算符和自动拆箱导致了空指针异常。

根据规定,三目运算符的第二、第三位操作数的返回值类型应该是一样的,这样才能当把一个三目运算符的结果赋值给一个变量 。

如:Person i = a>b ? i1:i2;  ,就要求i1和i2的类型都必须是Person才行。

因为Java中存在一种特殊的情况,那就是基本数据类型和包装数据类型可以通过自动拆装箱的方式互相转换。即可以定义int i = new Integer(10);也可以定义Integer i= 10;

那如果,三目运算符的第二位和第三位的操作数的类型分别是基本数据类型和包装类型对象时 ,就需要有一方需要进行自动拆装箱 。

那到底如何做的呢,根据三目运算符的语法规范。参见jls-15.25,摘要如下:

If the second and third operands have the same type (which may be the null type), then that is the type of the conditional expression.

If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T.

If one of the second and third operands is of the null type and the type of the other is a reference type, then the type of the conditional expression is that reference type.

简单的来说就是:当第二 ,第三位操作数分别为基本类型和对象时,其中的对象就会拆箱为基本类型进行操作。

所以,结果就是:由于使用了三目运算符 ,并且第二、第三位操作数分别是基本类型和对象 。所以对对象进行拆箱操作 ,由于该对象为null,所以在拆箱过程中调用lue()的时候就报了NPE。

五 、问题解决

如果代码这么写,就不会报错:

Map<String,Boolean>map=newHashMap<String,Boolean>();Booleanb=(map!=null?(test):);

就是保证了三目运算符的第二第三位操作数都为对象类型。

这和三目运算符有关 。

网站收录博客

如何让百度收录 GitHub Pages 个人博客

很多程序员朋友都有在 GitHub Pages 上搭建自己的个人博客 ,对于个人博客,没有被搜索引擎收录的话,别人基本是是看不到的 ,再好的技术文无法被分享也是白搭。

基于 GitHub Pages 的个人博客, Google 收录非常及时全面。然而,到目前为止 ,GitHub 还是拒绝百度爬虫的访问,直接返回 403 。

官方给出原因是,百度爬虫爬得太狠 ,影响了 Github Pages 服务的正常使用 。这就导致了,但凡在 Github Pages 搭建的个人博客,都无法被百度收录。

现有的解决办法

1、使用 http:// 建立镜像网站

我之前使用过 http:// ,在本地 repo 的配置文件中同时添加 GitHub 和 http:// 远程 repo 地址 ,发布时,两边都会部署到,加上域名智能解析 ,对于国内的请求,转发到 Coding Page 即可。

但是通过 http:// 访问个人主页时会先出现跳转页面,导致百度无法正确爬取 。

2、利用 CDN

这个没试过 ,理论上来说,百度在第一次爬取时,CDN 上必须要已经有相应页面的缓存 ,否则,爬取的请求会被转发到 GitHub 源站,GitHub 还是会拒绝。

3 、使用 Nginx 反向代理

Nginx 做反向代理 ,直接代理百度爬虫,去 GitHub Pages 请求,然后将结果返回给百度爬虫。

这种方式可行 ,只不过 ,这些方法都需要一定的定制能力,对于个人开发者,还得买一台 VPS 或者云服务器 。

可靠、免费还简单的方法

Guillermo Rauch 大神创业搞了一个静态站 hosting 服务 ,可以通过 GitHub Hooks 实现自动部署,zeit 提供 存储 + CDN + DNS 一套完整的服务。

我给个人网站配置完成后,去百度站长试了一下 ,发现抓取成功了,sitemap 也提交成功了,坐等百度收录。

下面我把配置的步骤记录下来 ,给有需要的朋友一个参考 。

zeit 网站主要就三个步骤:

  • Github 账户登陆 http://,授予 zeit repo 的 read 权限;
  • 导入 GitHub 博客 repo;

  • 稍等片刻,部署成功。

项目名中的 . 自动替换成 - ,生成了一个类似于 `` 的链接,点击可以访问你的博客主页,这时候静态资源已经部署到 zeit 的边缘 CDN 节点上了 ,下次你 GitHub 项目的任何更新会触发 zeit 项目更新。

接下来的就是切换域名 ,通过智能 DNS 将国内流量切过去 。通过 http:// 提供的 DNS 解析服务配置自己的域名,然后在百度站长里配置信息。

在 Domains 下为项目添加你的个人域名。

我添加后出现以下配置错误,原因我的域名权威 dns 是 dnspod 。

一种解决方式是将直接使用 zeit 提供的 nameserver 智能 DNS ,另一种方式,就是保留 dnspod 作为权威 dns 服务器,但是要添加一条 ANAME 记录 。

有两张配置方式 ,一种是改 nameserver,我用的是这种,权威 dns 服务器改成左边那些 ,我看到你还是用的 dnspod 来解析的。另一种方式,就是保留 dnspod 作为权威 dns 服务器,但是要添加一条 ANAME 记录。

我使用的是第一种方式 ,直接在阿里云替换了 DNS 服务器,直接用 zeit 提供的 nameserver 智能 DNS 。

回到 zeit,刷新下 ,正常是这样 ,这里是给你签发 https 证书,免费的。

过一会儿应该就好了。

看一下 DNS 解析地址,说明 zeit 域名已经配置成功了 。

最后就是在百度站长里面添加个人域名了。这里注意选择 https 协议 ,因为 zeit 默认都是 https 了。

网站验证我采用的是文件验证,下载验证文件放在你博客本地 repo 的 source 目录下,部署到 GitHub ,当然也会及时更新到 zeit 。然后完成验证就好了,试一下链接诊断,看能不能正常抓取 ,失败的话,看看抓取的 ip 地址是不是还是之前的缓存,等待一段时间重新抓取下 ,时间取决于 dns 的 ttl。

从 官网上看,台湾和香港都有 CDN 节点,免费账户可以有 20G/月 ,个人博客应该是够用了。

配置还是很简单的 ,赶紧试试吧,有问题欢迎交流 。

有个地方写错了,应该是http://

博客网站有哪些

如何在新浪上收录博客网页

这个是给你找提交你博客文章的网址的登入口希望对你有所帮助 ,谢谢/新浪博主:快乐简单丰富 努力给在百度用户的好友们服务,一起努力快乐,简单生活 ,创造我们丰富的明天!!!

网站收录博客

网站和博客哪个更容易被百度收录

博客容易被收录,但是网站收录了不容易掉,博客的话也不是说容易掉 ,但是不是好的关键词就容易掉下去百度,新浪,搜狐 ,网易。
目前这4个博客是收录最高的,但是百度青睐的自然是自己的产品了,所以还是百度空间,百科 ,百度知道 ,百度贴吧,这些都可以帮助被百度抓取,原创当然是最重要的 ,下来就是更新,和好友互动。
这些都是被百度收录的前提条件 。
最快速让百度收录你的博客或者网站方法步骤: 1、申请博客 2 、更新原创文章 申请完博客后需要更新原创文章,这里必须是原创的 ,可以是自己的日记,心情,自己写的文章什么的 ,最好不要伪原创,因为这些文章百度也是收录的 。
注意事项:刚更新的文章里面不要加链接,加链接的话可以做个友情链接。
文章里面要加链接的话最好等博客更新的文章多的时候 ,至少一个星期,不然不收录。
3、逛其他博客 这一步最重要,只有通过逛其他博客才能让百度找的我们 ,这里选择也是有技巧的 ,先打开新浪博客首页,随便找一个博客链接进去留言 。
注意事项:留言的时候一定要用自己的博客账号登陆后留言,不要用隐名评理 ,不然就没有了。
还有看着留言多的就别留了,能抢到第一页就留,后面留了也没用。
告诉大家一个小技巧 ,一般在早上9点到11点之间去留言,一般都能抢到第一页 。
另外,也可以随时去搜索最新的博客抢沙发。
选择博客 ,输入要搜索的内容,搜索出来的都是最新更新的文章。

博客网站有哪些

一篇文章同时发到网站和博客上,博客被收录了对网站有影响吗

如果你想做好网站的优化排名 ,建议一样的文章不要重复发第二次,可以等待收录,如果一直不收录 ,可以提交链接给百度站长 。
如果提交也一直没有用 ,还是不收录的话,那就发到博客里吧,博客里收录应该挺快的 ,可以在某个段落中加入自己的词,相对文本更容易收录,但不要广告痕迹太明显噢 ,会通不过或者被删

本文版权归去快排wWw.seogUrublog.com 所有,如有转发请注明来出,竞价开户托管,seo优化请联系qq❉61910465