zoukankan      html  css  js  c++  java
  • 平时发现的一些有意思的小知识

    平时遇到的一些自己开始不懂,后来看了下原理,豁然开朗的问题:

    1.

     1 package day1226;
     2 
     3 /**
     4  * @author : hao
     5  * @project : StudySjms
     6  * @description :
     7  * @time : 2018/12/26 15:54
     8  */
     9 public class IntegerTest {
    10 
    11     public static void main(String[] args) {
    12         Integer i1 = 100;
    13         Integer i2 = 100;
    14         Integer i3 = 200;
    15         Integer i4 = 200;
    16         System.out.println(i1==i2);    //true
    17         System.out.println(i3==i4);  //false
    18     }
    19 }

    这是为什么呢? 开始我以为只是false就好了

    这里面体现了 原生类型和包装类型的装箱和拆箱。 

    自动装箱的时候 实际上调用了Interger.valueOf(int)  ,拆箱的时候用的是initValue(Integer)

    1     public static Integer valueOf(int i) {
    2         if(i >= -128 && i <= IntegerCache.high)
    3             return IntegerCache.cache[i + 128];
    4         else
    5             return new Integer(i);
    6     }

    可以发现如果值是-128-127范围内是返回缓存里的引用,如果不是新建一个对象,返回引用。所有上面200两个引用是两个对象的,所以false。

    2.你了解可变参数和数据参数吗?

     1 package day1227;
     2 
     3 /**
     4  * @author : hao
     5  * @project : StudySjms
     6  * @description :
     7  * @time : 2018/12/27 15:48
     8  */
     9 public class KbArrayTest {
    10 
    11 
    12     public static void main(String[] args) {
    13         KbArrayTest test = new KbArrayTest();
    14         int[] array = new int[]{1,2,3};
    15 
    16         test.printA(array);
    17         test.printB(array);
    18 
    19         test.printA(new int[]{3,4,5});
    20         test.printA(3,5,7);
    21         
    22         test.printB(new int[]{3,4,5});
    23         //test.printB(3,5,7); 不通过,   int...num参数可以接受数组,反之int[] array 不接受1,2,3这种参数
    24     }
    25 
    26 
    27 
    28     private void printA(int... num){
    29         for (int i = 0; i < num.length; i++) {
    30             System.out.println(num[i]);
    31         }
    32     }
    33 
    34     private void printB(int[] array){
    35         for (int i = 0; i < array.length; i++) {
    36             System.out.println(array[i]);
    37         }
    38     }
    39 }

    这里面看一下编译后的class 有意思的地方:

     1 //
     2 // Source code recreated from a .class file by IntelliJ IDEA
     3 // (powered by Fernflower decompiler)
     4 //
     5 
     6 package day1227;
     7 
     8 public class KbArrayTest {
     9     public KbArrayTest() {
    10     }
    11 
    12     public static void main(String[] args) {
    13         KbArrayTest test = new KbArrayTest();
    14         int[] array = new int[]{1, 2, 3};
    15         test.printA(array);
    16         test.printB(array);
    17         test.printA(new int[]{3, 4, 5});
    18         test.printA(new int[]{3, 5, 7});
    19         test.printB(new int[]{3, 4, 5});
    20     }
    21 
    22     private void printA(int... num) {
    23         for(int i = 0; i < num.length; ++i) {
    24             System.out.println(num[i]);
    25         }
    26 
    27     }
    28 
    29     private void printB(int[] array) {
    30         for(int i = 0; i < array.length; ++i) {
    31             System.out.println(array[i]);
    32         }
    33 
    34     }
    35 }

    调用 int... num 形参的方法,不管你参数怎么写,编译后都变成了 new int[]{} 数组参数的形式

    3. ArrayList里面的elementData [] 为什么用transient修饰。Arraylist不是支持序列化吗?

      应该知道transient修饰的变量内容是不参与自动序列化,即使实现了Serialiazble接口

      因为Arraylist里面数组的长度不是固定的,如果扩容后,这个data数据里面会有很多空的内容,这个就不需要去序列化了,

      ArrayList里面有两个类来实现序列化,writeObject和readObject 里面都是先写或者先读容量,然后挨个节点读或者写

    4.ArrayList 在多线程里面 如果后续用Iterator迭代器遍历,如果一个线程正在遍历,两一个线程修改了,那么会出现ConcurrentModificationException?知道原因吗?知道怎么解决吗?原理知道吗?

      首先ArrayList的父类AbstractList里面实现乐迭代器接口并且在hasNext和next()方法里都做了判断,是否抛这个异常,有一个modCount,和Iterator也有个ExpectedModCount,

    然后每次ArrayList改变数组大小操作的时候,都是modCount+1,但是new Itreator的时候给的初始值是原来的,这样就导致可能出现不一致的情况。

      然后解决这个问题可以用CopyOnWriteArrayList来解决。

      为什么可以呢? 因为这个类所有写操作都加锁,然后每次操作都会复制一份原来的数组,改好了在把新数组的引用指向原来的,数组,而且这个array是用volatile修饰的,内存可见性。而且他的iterator是自己实现的。数组也是备份了一份,所以遍历的时候不会影响的。因为Iterator操作的还是老的数组,

  • 相关阅读:
    高并发处理(一)页面静态化
    高并发处理(二)图片服务器分离
    五百强企业某部门视频面试题汇总
    access和sqlyog的使用
    条件查询
    primary select |||| case primary select
    win10 + ubuntu16 双系统安装
    ubuntu16 下安装python3.6 和Anaconda3
    import nltk nltk.download('reuters') [nltk_data] Error loading reuters: <urlopen error [Errno 11004] [nltk_data] getaddrinfo failed>
    共现矩阵
  • 原文地址:https://www.cnblogs.com/haoerlv/p/10179685.html
Copyright © 2011-2022 走看看