• java几个常见的基础错误


    1.String 相等

    稍微有点经验的程序员都会用equals比较而不是用 ==,但用equals就真的安全了吗,看下面的代码

    user.getName().equals("xiaoming");

    有经验的老司机很快就能看到问题,如果user.getName()为null,就会抛出空指针异常,因此下面的写法更为稳妥

    "xiaoming".equals(user.getName());

    当然这种写法并不是万能的,如果比对的两边都是未知变量,如下

    user.getName().equals(user1.getName());//user.getName() 和 user1.getName()都有可能为null

    因此更为稳妥的方法可以采用jdk Objects类中的equals方法,左右两边都可以避免空指针异常

    Objects.equals(user.getName(), user1.getName());

    需要注意的是Objects类在jdk1.7才支持,如果是jdk1.6,可以采用guava中的Objects类代替

    2.Integer 比较

    Integer a = 127;
    Integer b = 127;
    Integer c = 128;
    Integer d = 128;
    System.out.println(a == b);// 结果为:true
    System.out.println(c == d);// 结果为:false

    令人惊讶的是结果并不是预料中的全是true,而是一个为true,一个为false
    至于原因还需要从源码中探究

    首先通过源码来看一下,当通过 = 对Integer赋值时,实际调用了Integer.valueOf()方法

    public static Integer valueOf(int i) {
        assert IntegerCache.high >= 127;
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

    可以看到当 i >= IntegerCache.low && i <= IntegerCache.high 时,是从一个缓存类中取,其它情况会new一个对象。IntegerCache.low默认为-128,high默认为127(可调整)。

    这样a=b就很好解释了,因为==比较的是内存地址,a,b都是从这个缓存类中取的同一个对象,所以返回结果为true。b,c则都是new的新对象,内存地址自然不同,所以返回false

    既然看到了这个缓存类,就有必要一睹它的庐山真面目了

    private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];
    
        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            }
            high = h;
    
            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
        }
    
        private IntegerCache() {}
    }

    IntegerCache 是Integer类中一个静态内部类,high值可通过JVM 的启动参数设置

    3.Arrays.asList(array)

    String [] array= {"a","b","c"};
    // 返回的List实例为:java.util.Arrays.ArrayList
    List<String> list = Arrays.asList(array);
    list.remove(0);

    Arrays.asList是一种很常见的创建List的方式,但该方法返回的List实例不是平时常用的List实例,而是Arrays的一个静态内部类,该类继承自AbstractList类,并为提供List的完整的实现,例如remove方法就未实现,当然,如果只是用做遍历,则完全是没问题的

    类似的情况还有不少,使用时要注意,例如:

    1. ArrayList的subList方法,返回的是ArrayList中的一个内部类java.util.ArrayList.SubList
    2. HashMap的values方法,返回的是HashMap中的一个内部类:java.util.HashMap.Values

    4.list.toArray

    List<String> list = new ArrayList<String>();
    String[] array=(String[]) list.toArray();

    上面的写法乍一看似乎没有什么问题,但list.toArray()返回的是一个object数组,强转会抛异常。其实是可以指定返回数组的类型的,如下

    String[] array=list.toArray(new String[list.size()]);

    5.foreach remove

    List<String> list =new ArrayList<String>();
    list.add("java");
    list.add("c");
    list.add("js");
    for(String str:list){
      list.remove(0);
    }

    在遍历时删除元素也是比较常用的操作,但foreach时删除元素有可能抛异常,这种不好控制的写法还是不用为好,可以用迭代器去代替

    for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
      String str = iterator.next();
      iterator.remove();
    }

    6. String getBytes

    String str="韦德";
    byte[] bytes = str.getBytes();

    String的getBytes()方法用的是当前项目的默认编码,如果不指定编码,在不同的运行环境很容易被坑,所以还是根据自己的需要指定对应的编码比较靠谱

    String str="韦德";
    byte[] bytes = str.getBytes("utf-8");





    作者:zhaoguhong(赵孤鸿)

    出处:http://www.cnblogs.com/zhaoguhong/

    本文版权归作者和博客园共有,转载请注明出处

    人生必有痴,然后有成。所以成功的人,非疯即傻
  • 相关阅读:
    多线程频繁上锁同步还不如用单线程
    1分钟左右随机生成2000万行随机字符串
    语言:抽象,封装,底层,低级
    构建WDK驱动出现fatal error U1087: cannot have : and :: dependents for same target
    Cmake编译成静态库
    VMware虚拟机相关文件问题
    输出流重定向
    How can I let the compiled script depend on something dynamic
    应用服务攻击工具clusterd
    Kali Linux缺少ifconfig命令
  • 原文地址:https://www.cnblogs.com/Shawn-Liu/p/7605704.html
Copyright © 2020-2023  润新知