Jdk源码一:java.lang包下的常用类

此系列博文主要记录在阅读Jdk源码过程中遇到的问题及一些小的知识点,如理解有误之处,可留言提出。


Object 类

       clone

       如果一个类仅包含基本字段或对不可变对象的引用,通常情况下,clone后的对象可认为是深拷贝,若包含对象的引用,如果要实现深拷贝,那么对象本身需要实现clone方法,修改返回的对象中的对象引用。

equal

reflexive(自反)symmetric(对称)transitive(传递)consistent(一致)

hashcode 
        If two objects are equal according to the {@code equals(Object)} method, 
        then calling the {@code hashCode} method on each of the two objects must produce the same integer result.

 wait 
        notify 
        notifyAll
        toString
        finalize

String类

String implements java.io.Serializable, Comparable<String>, CharSequence 
        private final char value[]; 不可变字符序列
        重点:
        1.Sting 对象的两种创建方式
        https://www.cnblogs.com/developer_chan/p/8608410.html
        2.拼接时如果有对象:
        String a = "a"
        String d = "ab"
        String b = a + "b"  ==>  d == b  false 
        创建b时是直接在堆上创建,b指向的是堆中对象的内存地址 (因为包含对象,所以是在运行时创建)
        String c = "a" + "b"     d == c true     (编译时创建)
        3.intern方法
        String f = d.intern() 如果字符串常量池中有指向某个对象(e)的引用e.equals(d) 那么f指向与e指向同一个对象
                              如果没有,那么先在堆上创建,然后放入常量池中,再返回一个对象的引
        4.hashcode()
        使用31作为一个乘子(是个大小合适的质数)
           

 for (int i = 0; i < value.length; i++) {
          h = 31 * h + val[i];
     }
      hash = h;


        5.静态方法String.valueOf (以public static String valueOf(int i) 举例说明)
            调用了Integer.toString(i) 
           

 public static String toString(int i) {
        ........
        return new String(buf, true);
   }


            每次返回的时在堆中新创建的String对象
            所以:
                String a = String.valueOf(1);
                String b = String.valueOf(1);
                a == b      ==>  fasle
                a.equals(b) ==>  true

AbstractStringBuilder类

AbstractStringBuilder implements Appendable, CharSequence
        char[] value;  可变字符序列 
       重点:
        1.expandCapacity 扩容为原length*2 + 2 如果 < minimumCapacity 则扩容为 minimumCapacity
                  

    int newCapacity = value.length * 2 + 2;
    if (newCapacity - minimumCapacity < 0)
        newCapacity = minimumCapacity;


        2.主要子类 StringBuffer StringBuilder
            区别:StringBuffer多线程安全(使用 synchronized),StringBuilder线程不安全
                StringBuffer 锁的是StringBuffer对象并非源char[],作为参数传递的时候(多线程情况下源char[]会被修改的风险)
            主要方法 append insert

Integer类

Integer extends Number implements Comparable<Integer>
        1.


    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");


        私有的静态内部类IntegerCache 持有一个静态的Integer[] 作为缓存 可以通过java.lang.Integer.IntegerCache.high 调整最大的缓存范围
        2.

public static int highestOneBit(int i) {
        // HD, Figure 3-1
        i |= (i >>  1);
        i |= (i >>  2);
        i |= (i >>  4);
        i |= (i >>  8);
        i |= (i >> 16);
        return i - (i >>> 1);
    }


            整体思想:将i最高位往后的所有bit位置为1,然后无符号右移做减法运算
            获取最高位的数值
        3.

public static int lowestOneBit(int i) {
        // HD, Section 2-1
        return i & -i;
    }


        获取最低位的数值
        4.

public static int numberOfLeadingZeros(int i) {
        // HD, Figure 5-6
        if (i == 0)
            return 32;
        int n = 1;
        if (i >>> 16 == 0) { n += 16; i <<= 16; }
        if (i >>> 24 == 0) { n +=  8; i <<=  8; }
        if (i >>> 28 == 0) { n +=  4; i <<=  4; }
        if (i >>> 30 == 0) { n +=  2; i <<=  2; }
        n -= i >>> 31;
        return n;
    }


        获取二进制前导0的个数
        5.

public static int numberOfTrailingZeros(int i) {
        // HD, Figure 5-14
        int y;
        if (i == 0) return 32;
        int n = 31;
        y = i <<16; if (y != 0) { n = n -16; i = y; }
        y = i << 8; if (y != 0) { n = n - 8; i = y; }
        y = i << 4; if (y != 0) { n = n - 4; i = y; }
        y = i << 2; if (y != 0) { n = n - 2; i = y; }
        return n - ((i << 1) >>> 31);
    }


        获取二进制后置0的个数
        6.

public static int bitCount(int i) {
        // HD, Figure 5-2
        i = i - ((i >>> 1) & 0x55555555);
        i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
        i = (i + (i >>> 4)) & 0x0f0f0f0f;
        i = i + (i >>> 8);
        i = i + (i >>> 16);
        return i & 0x3f;
    }


        计算二进制位上为1的位数
        不能理解:rotateLeft rotateRight reverse signum reverseBytes
        
        下面我们进行一个归类: 
        Integer派别:Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。 
        缓存范围:
            Byte,Short,Integer,Long为 -128 到 127
            Character范围为 0 到 127
        Double派别:Double、Float的valueOf方法的实现是类似的。每次都返回不同的对象。

ThreadLocal类

在线程内部存在一个ThreadLocal.ThreadLocalMap ,ThreadLocalMap 是TreadLocal内部的一个静态类,持有一个Entry[]
        里面存储的Entry对象以变量ThreadLocal对象(是个弱引用,Entry继承自WeakReference,会在YGC时被回收))的hashcode为key,想要存储的变量为value。
        问题1:为啥使用弱引用?
            分两种情况:
                1.使用强引用的话,如果持有ThreadLocal的对象被回收,但是由于还有ThreadLocalMap在引用ThreadLocal对象,那么在线程
            存活的时候,ThreadLocal对象本身不会被回收,造成内存泄露。
                2.使用弱引用,持有ThreadLocal的对象被回收的话,在YGC的时候ThreadLocalMap引用ThreadLocal为弱引用,ThreadLocal就会
            被彻底回收,从而避免的ThreadLocal对象造成的内存泄露,存储在ThreadLocalMap中key为null的Entry会在调用set get remove 方法时
            被回收。
        问题2:为啥推荐使用完后主动调用remove方法?
            情形1:
                将ThreadLocal声明为static类型的变量,延长了ThreadLocal对象的生存周期,这样的话,GC的时候Entry对象也同样不会被回收。调用set get方法也不会
            (set get方法清除的是key为null的Entry对象),造成内存泄露。
            情形2:
                调用ThreadLocal set方法后,持有ThreadLocal对象的对象被回收后,再也没有调用过set get 方法,这时Entry的key即使为null也不会被
            回收,造成内存泄露。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值