当前位置: 首页 > news >正文

泉州网站建设wordpress教

泉州网站建设,wordpress教,汕头室内设计公司排名,无障碍 网站 怎么做前言作为Java程序员的你#xff0c;不知道有没有踩过一些基础知识的坑。有时候#xff0c;某个bug#xff0c;你查了半天#xff0c;最后发现竟然是一个非常低级的错误。有时候#xff0c;某些代码#xff0c;这一批数据功能正常#xff0c;但换了一批数据就出现异常了。… 前言作为Java程序员的你不知道有没有踩过一些基础知识的坑。有时候某个bug你查了半天最后发现竟然是一个非常低级的错误。有时候某些代码这一批数据功能正常但换了一批数据就出现异常了。有时候你可能会看着某行代码目瞪口呆心里想这行代码为什么会出错今天跟大家一起聊聊99%的Java程序员踩过或者即将踩的6个坑。1. 用号比较的坑不知道你在项目中有没有见过有些同事对Integer类型的两个参数使用号比较是否相等反正我见过的那么这种用法对吗我的回答是看具体场景不能说一定对或不对。有些状态字段比如orderStatus有-1(未下单)0已下单1已支付2已完成3取消5种状态。这时如果用判断是否相等Integer orderStatus1  new Integer(1); Integer orderStatus2  new Integer(1); System.out.println(orderStatus1  orderStatus2);返回结果会是true吗答案是false。有些同学可能会反驳Integer中不是有范围是-128-127的缓存吗为什么是false先看看Integer的构造方法它其实并没有用到缓存。那么缓存是在哪里用的答案在valueOf方法中如果上面的判断改成这样String orderStatus1  new String(1); String orderStatus2  new String(1); System.out.println(Integer.valueOf(orderStatus1)  Integer.valueOf(orderStatus2));返回结果会是true吗答案还真是true。我们要养成良好编码习惯尽量少用判断两个Integer类型数据是否相等只有在上述非常特殊的场景下才相等。而应该改成使用equals方法判断Integer orderStatus1  new Integer(1); Integer orderStatus2  new Integer(1); System.out.println(orderStatus1.equals(orderStatus2));运行结果为true。2. Objects.equals的坑假设现在有这样一个需求判断当前登录的用户如果是我们指定的系统管理员则发送一封邮件。系统管理员没有特殊的字段标识他的用户id888在开发、测试、生产环境中该值都是一样的。这个需求真的太容易实现了UserInfo userInfo  CurrentUser.getUserInfo();if(Objects.isNull(userInfo)) {log.info(请先登录);return; }if(Objects.equals(userInfo.getId(),888L)) {sendEmail(userInfo): }从当前登录用户的上下文中获取用户信息判断一下如果用户信息为空则直接返回。如果获取到的用户信息不为空接下来判断用户id是否等于888。如果等于888则发送邮件。如果不等于888则啥事也不干。当我们用id888的系统管理员账号登录之后做了相关操作满怀期待的准备收邮件的时候却发现收了个寂寞。后来发现UserInfo类是这样定义的Data public class UserInfo {private Integer id;private String name;private Integer age;private String address; }此时有些小伙伴可能会说没看出什么问题呀。但我要说的是这个代码确实有问题。什么问题呢下面我们重点看看它的equals方法public static boolean equals(Object a, Object b) {return (a  b) || (a ! null  a.equals(b)); }equals方法的判断逻辑如下该方法先判断对象a和b的引用是否相等如果相等则直接返回true。如果引用不相等则判断a是否为空如果a为空则返回false。如果a不为空调用对象的equals方法进一步判断值是否相等。这就要从Integer的equals方法说起来了。它的equals方法具体代码如下public boolean equals(Object obj) {if (obj instanceof Integer) {return value  ((Integer)obj).intValue();}return false; }先判断参数obj是否是Integer类型如果不是则直接返回false。如果是Integer类型再进一步判断int值是否相等。而上面这个例子中b是long类型所以Integer的equals方法直接返回了false。也就是说如果调用了Integer的equals方法必须要求入参也是Integer类型否则该方法会直接返回false。除此之外还有Byte、Short、Double、Float、Boolean和Character也有类似的equals方法判断逻辑。常见的坑有Long类型和Integer类型比较比如用户id的场景。Byte类型和Integer类型比较比如状态判断的场景。Double类型和Integer类型比较比如金额为0的判断场景。如果你想进一步了解Objects.equals方法的问题可以看看我的另一篇文章《Objects.equals有坑》。3. BigDecimal的坑通常我们会把一些小数类型的字段比如金额定义成BigDecimal而不是Double避免丢失精度问题。使用Double时可能会有这种场景double amount1  0.02; double amount2  0.03; System.out.println(amount2 - amount1);正常情况下预计amount2 - amount1应该等于0.01但是执行结果却为0.009999999999999998实际结果小于预计结果。Double类型的两个参数相减会转换成二进制因为Double有效位数为16位这就会出现存储小数位数不够的情况这种情况下就会出现误差。常识告诉我们使用BigDecimal能避免丢失精度。但是使用BigDecimal能避免丢失精度吗答案是否定的。为什么BigDecimal amount1  new BigDecimal(0.02); BigDecimal amount2  new BigDecimal(0.03); System.out.println(amount2.subtract(amount1));这个例子中定义了两个BigDecimal类型参数使用构造函数初始化数据然后打印两个参数相减后的值。结果0.0099999999999999984734433411404097569175064563751220703125不科学呀为啥还是丢失精度了Jdk中BigDecimal的构造方法上有这样一段描述大致的意思是此构造函数的结果可能不可预测可能会出现创建时为0.1但实际是0.1000000000000000055511151231257827021181583404541015625的情况。由此可见使用BigDecimal构造函数初始化对象也会丢失精度。那么如何才能不丢失精度呢BigDecimal amount1  new BigDecimal(Double.toString(0.02)); BigDecimal amount2  new BigDecimal(Double.toString(0.03)); System.out.println(amount2.subtract(amount1));我们可以使用Double.toString方法对double类型的小数进行转换这样能保证精度不丢失。其实还有更好的办法BigDecimal amount1  BigDecimal.valueOf(0.02); BigDecimal amount2  BigDecimal.valueOf(0.03); System.out.println(amount2.subtract(amount1));使用BigDecimal.valueOf方法初始化BigDecimal类型参数也能保证精度不丢失。在新版的阿里巴巴开发手册中也推荐使用这种方式创建BigDecimal参数。4. Java8 filter的坑对于Java8中的Stream用法大家肯定再熟悉不过了。我们通过对集合的Stream操作可以实现遍历集合、过滤数据、排序、判断、转换集合等等N多功能。这里重点说说数据的过滤。在没有Java8之前我们过滤数据一般是这样做的public ListUser filterUser(ListUser userList) {if(CollectionUtils.isEmpty(userList)) {return Collections.emptyList();}ListUser resultList  Lists.newArrayList();for(User user: userList) {if(user.getId()  1000  user.getAge()  18)   {resultList.add(user);}}return resultList; }通常需要另一个集合辅助完成这个功能。但如果使用Java8的filter功能代码会变得简洁很多例如public ListUser filterUser(ListUser userList) {if(CollectionUtils.isEmpty(userList)) {return Collections.emptyList();}return userList.stream().filter(user - user.getId()  1000  user.getAge()  18).collect(Collectors.toList()); }代码简化了很多完美。但如果你对过滤后的数据做修改了ListUser userList  queryUser(); ListUser filterList  filterUser(userList); for(User user: filterList) {user.setName(user.getName()  测试); }for(User user: userList) {System.out.println(user.getName()); }你当时可能只是想修改过滤后的数据但实际上你会把元素数据一同修改了。意不意外惊不惊喜其根本原因是过滤后的集合中保存的是对象的引用该引用只有一份数据。也就是说只要有一个地方把该引用对象的成员变量的值做修改了其他地方也会同步修改。如下图所示5. 自动拆箱的坑Java5之后提供了自动装箱和自动拆箱的功能。自动装箱是指JDK会把基本类型自动变成包装类型。比如Integer integer  1;等价于Integer integer  new Integer(1);而自动拆箱是指JDK会把包装类型自动转换成基本类型。例如Integer integer  new Integer(2); int sum  integer  5;等价于Integer integer  new Integer(2); int sum  integer.intValue()  5;但实际工作中我们在使用自动拆箱时往往忘记了判空导致出现NullPointerException异常。5.1 运算很多时候我们需要对传入的数据进行计算例如public class Test2 {public static void main(String[] args) {System.out.println(add(new Integer(1), new Integer(2)));}private static Integer add(Integer a, Integer b) {return a  b;} }如果传入了null值System.out.println(add(null, new Integer(2)));则会直接报错。5.2 传参有时候我们定义的某个方法是基本类型但实际上传入了包装类比如public static void main(String[] args) {Integer a  new Integer(1);Integer b  null;System.out.println(add(a, b)); }private static Integer add(int a, int b) {return a  b; }如果出现add方法报NullPointerException异常你可能会懵逼int类型怎么会出现空指针异常呢其实这个问题出在Integer类型的参数其实际传入值为nullJDK字段拆箱调用了它的intValue方法导致的问题。6. replace的坑很多时候我们在使用字符串时想把字符串比如ATYSDFA*Y中的字符A替换成字符B第一个想到的可能是使用replace方法。如果想把所有的A都替换成B很显然可以用replaceAll方法因为非常直观光从方法名就能猜出它的用途。那么问题来了replace方法会替换所有匹配字符吗jdk的官方给出了答案。该方法会替换每一个匹配的字符串。既然replace和replaceAll都能替换所有匹配字符那么他们有啥区别呢replace有两个重载的方法。其中一个方法的参数char oldChar 和 char newChar支持字符的替换。source.replace(A, B)另一个方法的参数是CharSequence target 和 CharSequence replacement支持字符串的替换。source.replace(A, B)而replaceAll方法的参数是String regex 和 String replacement即基于正则表达式的替换。例如对普通字符串进行替换source.replaceAll(A, B)使用正则表达替换将*替换成Csource.replaceAll(\\*, C)顺便说一下将*替换成C使用replace方法也可以实现source.replace(*, C)小伙们看到看到二者的区别了没使用replace方法无需对特殊字符进行转义。不过千万注意切勿使用如下写法source.replace(\\*, C)这种写法会导致字符串无法替换。还有个小问题如果我只想替换第一个匹配的字符串该怎么办?这时可以使用replaceFirst方法source.replaceFirst(A, B)说实话这里内容都很基础但越基础的东西越容易大意失荆州更容易踩坑。最后统计一下这些坑一个都没踩过的同学麻烦举个手。
http://www.pierceye.com/news/188784/

相关文章:

  • 做DJ网站违法吗汕头seo网站推广
  • 上海网站建设网站宁波网站模板哪家性价比高
  • 珠海专业做网站制作做网站网站的代理算网站罪吗
  • 建设局网站简介通信建设网站
  • php做网站用什么开发工具大专软件技术工资一般多少
  • 网站建设服务承诺wordpress 博客园
  • seo综合查询站长工具关键词全网营销案例
  • 深圳专业做网站设计政务服务网站建设性建议
  • 做暧免费观看网站哪个网站可以给图片做链接
  • wordpress最好的主题东莞债务优化
  • 全国网站建设大赛网店网站设计
  • 学网站建设需要学多久wordpress火车头插件
  • wordpress 网站实例中国纪检监察报app下载
  • 网站链接dw怎么做营销推广方法
  • 觅知网 大而全的高质量素材站开发手机网站用什么好
  • 建设一个广告联盟的网站医院网站设计与实现
  • 公司网站备案必须是企业信息么网站搭建好有什么内容可以修改
  • 弄网站赚钱吗电影网站怎么做要多少钱
  • 做优化网站能以量取胜么好素材网站
  • wordpress主题网站江苏建设工程教育网
  • 网站制作 客户刁难做宠物网站赚钱吗
  • 网站突然不收录了如何形容一个网站做的好
  • 怎么建网站教程视频做网站跟推广哪家公司好
  • 怎么做网站报告四平网站公司
  • 飞扬动力网站建设支付网站建设要求
  • 达美网站建设廊坊seo扣费
  • 好享购物官方网站购物网页制作与网站开发从入门到精通
  • 坪山网站建设哪家便宜系部网站建设研究方案
  • 如何备份网站上海的招聘网站有哪些
  • 企业门户网站建设流程蝶恋花直播app下载安装