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

太原制作网站的公司网站网站建设容易出现的问题

太原制作网站的公司网站,网站建设容易出现的问题,网站策划书背景介绍,重庆地灾app下载官网最近我们通过sonar静态代码检测#xff0c;同时配合人工代码review#xff0c;发现了项目中很多代码问题。除了常规的bug和安全漏洞之外#xff0c;还有几处方法用法错误#xff0c;引起了我极大的兴趣。我为什么会对这几个方法这么感兴趣呢#xff1f;因为它们极具迷惑性… 最近我们通过sonar静态代码检测同时配合人工代码review发现了项目中很多代码问题。除了常规的bug和安全漏洞之外还有几处方法用法错误引起了我极大的兴趣。我为什么会对这几个方法这么感兴趣呢因为它们极具迷惑性可能会让我们傻傻分不清楚。1. 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) 无需对特殊字符进行转义。不过千万注意切勿使用如下写法source.replace(\\*, C) 这种写法会导致字符串无法替换。还有个小问题如果我只想替换第一个匹配的字符串该怎么办?这时可以使用replaceFirst方法source.replaceFirst(A, B) 2. Integer不能用判断相等不知道你在项目中有没有见过有些同事对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)); 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. 字符串拼接不能用StringString类型的字符串被称为不可变序列也就是说该对象的数据被定义好后就不能修改了如果要修改则需要创建新对象。String a 123; String b 456; String c a b; System.out.println(c); 在大量字符串拼接的场景中如果对象被定义成String类型会产生很多无用的中间对象浪费内存空间效率低。这时我们可以用更高效的可变字符序列StringBuilder和StringBuffer来定义对象。那么StringBuilder和StringBuffer有啥区别StringBuffer对各主要方法加了synchronized关键字而StringBuilder没有。所以StringBuffer是线程安全的而StringBuilder不是。其实我们很少会出现需要在多线程下拼接字符串的场景所以StringBuffer实际上用得非常少。一般情况下拼接字符串时我们推荐使用StringBuilder通过它的append方法追加字符串它只会产生一个对象而且没有加锁效率较高。String a 123; String b 456; StringBuilder c new StringBuilder(); c.append(a).append(b); System.out.println(c); 接下来关键问题来了字符串拼接时使用String类型的对象效率一定比StringBuilder类型的对象低答案是否定的。为什么使用javap -c StringTest命令反编译从图中能看出定义了两个String类型的参数又定义了一个StringBuilder类的参数然后两次使用append方法追加字符串。如果代码是这样的String a 123; String b 789; String c a b; System.out.println(c); 使用javap -c StringTest命令反编译的结果会怎样呢我们会惊讶的发现同样定义了两个String类型的参数又定义了一个StringBuilder类的参数然后两次使用append方法追加字符串。跟上面的结果是一样的。其实从jdk5开始java就对String类型的字符串的操作做了优化该操作编译成字节码文件后会被优化为StringBuilder的append操作。5. isEmpty和isBlank的区别我们在对字符串进行操作的时候需要经常判断该字符串是否为空。如果没有借助任何工具我们一般是这样判断的if (null ! source !.equals(source)) {System.out.println(not empty); } 但是如果每次都这样判断会有些麻烦所以很多jar包都对字符串判空做了封装。目前市面上主流的工具有spring中的StringUtilsjdbc中的StringUtilsapache common3中的StringUtils不过spring中的StringUtils类只有isEmpty方法没有isNotEmpty方法。jdbc中的StringUtils类只有isNullOrEmpty方法也没有isNotNullOrEmpty方法。所以在这里强烈推荐一下apache common3中的StringUtils类它里面包含了很多实用的判空方法isEmpty、isBlank、isNotEmpty、isNotBlank等还有其他字符串处理方法。问题来了isEmpty和isBlank有啥区别使用isEmpty方法判断 StringUtils.isEmpty(null) trueStringUtils.isEmpty() trueStringUtils.isEmpty( ) falseStringUtils.isEmpty(bob) falseStringUtils.isEmpty( bob ) false 使用isBlank方法判断StringUtils.isBlank(null) true StringUtils.isBlank() true StringUtils.isBlank( ) true StringUtils.isBlank(bob) false StringUtils.isBlank( bob ) false 两个方法关键的区别在于这种 空字符串的情况isNotEmpty返回false而isBlank返回true。6. mapper查询结果要判空有次代码review的时候当时有个同事说这里的判空可以去掉让我记忆犹新ListUser list userMapper.query(search); if(CollectionUtils.isNotEmpty(list)) {ListLong idList list.stream().map(User::getId).collect(Collectors.toList()); } 因为按常理一般调用方法查询出来的集合可能为null需要判空的。但是这里比较特殊我查了一下mybatis的源码这个判空的代码还真的可以去掉。怎么回事呢mybatis的查询方法最终都会调到DefaultResultSetHandler类的handleResultSets方法该方法会返回一个multipleResultsList集合对象在方法刚开始就new出来了肯定是不会为空。所以如果你在项目的代码中看到有人直接使用查询出的结果不判空也不要惊讶ListUser list userMapper.query(search); ListLong idList list.stream().map(User::getId).collect(Collectors.toList()); 因为mapper底层已经处理过的它不会出现空指针异常。7. indexOf方法的正确用法有次在review别人代码的时候看到有个地方indexOf使用了这种写法让我印象比较深刻String source #ATYSDFA*Y; if(source.indexOf(#) 0) {System.out.println(do something); } 你们说这段代码会打印出do something吗答案是否定的。为什么呢jdk官方说了不存在的情况会返回-1indexOf方法返回的是指定元素在字符串中的位置从0开始。而上面的例子#在字符串的第一个位置所以调用indexOf方法后的值其实是0。所以条件是false不会打印do something。如果想通过indexOf判断某个元素是否存在时要用if(source.indexOf(#) -1) {System.out.println(do something); } 其实还有更优雅的contains方法if(source.contains(#)) {System.out.println(do something); }
http://www.yutouwan.com/news/429730/

相关文章:

  • 网站设计 app开发网站开发工程师面试问题
  • php mysql 网站开发实例教程二级域名分发
  • 阿里云网站备案要多久校园二手物品交易网站怎么做
  • 建设电影播放网站建设公司网站的申请
  • 成都网站建设优创智汇统一企业信息管理系统网站
  • 如何申请免费域名做网站设计师投资做项目网站
  • 档案网站建设经验定制一款软件需要多少钱
  • 现在网站开发用什么dede导入wordpress
  • wordpress分类目录名称福州短视频seo方法
  • 技术网站源码wordpress百度霸屏全网推广
  • 免费建网站平台哪个好网站如何添加二维码
  • 怎样制作网站建设方案网站建设的公司太多了
  • 网站搭建详细步骤网站的首页面设计
  • 效果图网站有哪些怎么用一个主机做多个网站
  • 网站建设销售开场白用divid做网站代码
  • 网站内容建设的核心和根本是编程教学
  • 网站制作与管理技术标准实训教程wordpress andriod
  • 制作自己的网站多少钱外贸seo是什么意思
  • 宁海企业网站建设网站建设前端学什么语言
  • 网站建设的闪光点外网门户网站建设方案
  • wordpress简约下载站模板网站 301
  • 长春网站排名优化价格在线看视频网站怎么做
  • 灵武市建设银行网站做网站建
  • 都江堰城乡建设局网站wordpress登录不了
  • wordpress小工具文件seo网络推广机构
  • 那些网站做网批wordpress单页淘宝客
  • 电子商务网站的建设包含哪些流程图网站建设推广需要多少钱
  • 尉氏做网站网站降权如何百度申诉
  • seo优化网站推广专员招聘wordpress上传文件大小
  • 如何做登陆界面的网站网站建设销售员工作内容