深入Java基础(一)——基本数据类型及其包装类

在线重装系统:从原理到实践的全流程指南 系统重装是计算机维护中的基础操作,其核心原理是通过替换操作系统文件来恢复系统性能。在线重装技术利用网络下载系统镜像,在现有系统环境下直接完成安装,无需外部启动介质。这种方案的技术价值在于大幅降低操作门槛,让普通用户能够快速解决系统卡顿、软件冲突等常见问题。在应用场景上,它特别适合系统仍可正常启动但需要优化或升级的情况。通过合理选择工具和严格检查网络、磁盘等环境条件,在线重装可以高效完成系统修复。本文基于实际工程经验,重点解析Windows系统重置功能的操作流程和常见问题排查方法,帮助用户掌握这一便捷的维护技 阅读详情

作为一名程序员,我觉得会多门语言的前提,必须把一门语言熟练掌握,才能触类旁通,因此,也就出现了这次的Java基础与深入之旅啦!欢迎大家关注这一系列。

这一系列打算慢慢地去接触源码,并且列出相关的题目,对于完全的初学者的话,我到时候会搜一套我认为比较好的培训机构的视频以及给些社区资料和相关博客咯。让我们一起开始思考,深入学习Java吧。

这篇文章就数据类型咯-文章结构:1. 基本数据类型的系统描述;2.数据类型的包装类理解(含源码解析);3.数据类型转换、装包拆包等一些小坑。


一、基本数据类型的系统描述:

1. 总述:Java基本数据类型分为两大类:boolean类型和数值类型。数值类型可分为整数类型和浮点类型,而其中字符类型可单独对待。所以Java只包含8种基本数据类型。
!注意!字符串不是基本数据类型,字符串是一个类,是一个引用类型。这个在下一篇我们会仔细讨论它!
boolean 数值只有true和false,不能用0代替。其他数值类型不能转换成boolean。包装类–Boolean
byte 内存8位,无符号位时最大存储255,表数范围:-128~127。包装类–Byte
short 内存16位,无符号位时最大存储65536,表数范围:-32768~32767。包装类–Short
int 内存32位,无符号位时最大存储2的32次方减1,表数范围:负的2的31次方到正的2的31次方减1。包装类–Integer。
long 内存64位,无符号位时最大存储2的64次方减1,表数范围:负的2的63次方到正的2的63次方减1。包装类–Long。
float 内存32位,数据范围在3.4e-45~1.4e38,直接赋值时必须在数字后加上f或F。包装类–Float。
double 内存64位,数据范围在4.9e-324~1.8e308,赋值时可以加d或D也可以不加。包装类–Double。
char:16位,存储Unicode字符集,用单引号赋值。可以参与加减乘除运算的,也可以比较大小的!!包装类–Character。

二、数据类型的包装类理解(含部分源码解析)

首先要知道为什么Java会为每一个基础数据类型都提供一个相应包装类的目的,在于将Java的所有东西都抽象成对象,可以更方便的控制和使用。这就是面向对象!

然后对于包装类,主要作用是:1.作为和基本数据类型对应的类类型存在,方便涉及到对象的操作。2.包含每种基本数据类型的相关属性如最大值、最小值等,以及相关的操作方法。

下面我们将一起讨论下包装类中的重要源码!!

1.深入boolean基本类型、Boolean类以及细节点:
//看接口是可序列化,是一个final修饰的类
public final class Boolean implements java.io.Serializable,
                                      Comparable<Boolean>{
     //看这两个对应的原始对象。享元模式的使用,达到多个对象都使用一份内存。至于什么是享元,以及它与单例的区别,这里就不多说了。
     public static final Boolean TRUE = new Boolean(true);
     public static final Boolean FALSE = new Boolean(false);
     private final boolean value;
     //两个构造器,可见它是可以为null的啦,使用Boolean这个类的话
     public Boolean(boolean value) {
        this.value = value;
    }
     public Boolean(String s) {
        this(parseBoolean(s));
    }
     public static boolean parseBoolean(String s) {
        return ((s != null) && s.equalsIgnoreCase("true"));
    }
    //jdk文档建议用valueOf代替new方式来创建Boolean类对象。new创建的Boolean对象是不断的新创建一个实例对象,而valueOf则是返回Boolean类里的静态成员变量,也就是使用享元模式的那个对象。
    public static Boolean valueOf(String s) {
        return parseBoolean(s) ? TRUE : FALSE;
    }

    //下面是令人困惑的设计了,我也是看了下stackoverflow里面讨论才有点懂。
    //原汁原味链接:http://stackoverflow.com/questions/3912303/boolean-hashcode
    //1. 使用质素是因为假如要把Boolean指插入到hashtable中,如果不是质素的话可能会比较容易造成哈希冲突。符合对象计算hashcode的时候通常会把各个属性的hashcode相加然后再做hash,如果是比较小的质素,容易造成hash分布不均匀。
    //2. Maps是可以包裹Boolean的,而如果map除了包含Boolean对象,还包含其他对象,那么如果不适当处理,就很容易有冲突了
     public static int hashCode(boolean value) {
        return value ? 1231 : 1237;
    }
    //好恐怖和缜密的源码设计。
}




总括下:1.boolean是基础数据类型,而Boolean是一个类。2.boolean一般存在于桟空间中,而Boolean对象存在堆空间中。3.boolean有true和false俩种值,Boolean除了true和false外,还有null。

下面我们看份代码:(解析在代码中)

public class Main {
    public static void main (String []args)
    {
        Boolean bool1 = Boolean.valueOf(true);       //这里均使用valueof创建对象,new创建的Boolean对象是不断的新创建一个实例对象,而valueOf则是返回Boolean类里的静态成员变量
        Boolean bool2 = Boolean.valueOf("True");    //这里上一句代码验证使用String变量作为参数时,不区分大小写的。
        Boolean bool3 = Boolean.valueOf("ASD");
        boolean x1 = bool1.booleanValue();
        boolean x2 = bool2.booleanValue();
        System.out.println("bool1:" + x1 + ",bool2:" + x2 + ",bool3:" + bool3);
        boolean x3 = bool1.equals(bool2);       //这个就是验证享元模式,使用的是同一个对象
        boolean x4 = bool1.equals(bool3);       //肯定不是同一对象啦。
        System.out.println("bool1.equals(bool2):" + x3 + ",bool1.equals(bool3):" + x4);
        String str1 = Boolean.toString(bool1);      //可见Boolean对象是可以转换成字符的
        String str2 = Boolean.toString(false);      
        String str3 = bool3.toString();
        System.out.println("bool1:" + str1 + ",str2:" + str2 + ",bool3:" + str3);
        boolean x5 = Boolean.parseBoolean("ASD");         //源码是直接判断然后与true对比,因此打印为false
        System.out.println(x5);
    }
}




2.深入byte基本类型

先来份Byte源码
//也可以看到是一个final修饰的类,只能用,不能被继承咯
public final class Byte extends Number implements Comparable<Byte>{
    public static final int SIZE = 8;   //只能是一个字节咯
    //两个构造器
    public Byte(byte value) {
        this.value = value;   //传入的要为Byte类型的值
    }
    public Byte(String s) throws NumberFormatException {
        this.value = parseByte(s, 10);  //传入的要求是可转换成Byte的字符串
    }
    //这个Byte做了缓存
    private static class ByteCache {
        private ByteCache(){}

        static final Byte cache[] = new Byte[-(-128) + 127 + 1];//声明缓存数组的长度为256

        static {
            for(int i = 0; i < cache.length; i++)
                cache[i] = new Byte((byte)(i - 128));//然后将-128~127进行缓存
        }
    }
    //两个解析字符串方法
    public static byte parseByte(String s, int radix)
        throws NumberFormatException {
        //radix是解析字符串时候的基数,在此方法下有个解析基数的含义。
        int i = Integer.parseInt(s, radix);//解析字符串并返回,所以s必须是-128~127的字符,至于为什么用这个方法int的包装类方法来解析,一会我们会谈到。
        if (i < MIN_VALUE || i > MAX_VALUE)
            throw new NumberFormatException(
                "Value out of range. Value:\"" + s + "\" Radix:" + radix);
        return (byte)i;
    }
    //也是解码转码方法,将String转为Byte
    public static Byte decode(String nm) throws NumberFormatException {
        int i = Integer.decode(nm);//一会重点讲解Integer的系列方法
        if (i < MIN_VALUE || i > MAX_VALUE)
            throw new NumberFormatException(
                    "Value " + i + " out of range from input " + nm);
        return valueOf((byte)i);
    }
}




解释radix的作用
b[0] = Byte.parseByte(“11”, 2) = 3
表示 字符串11以2为基数表示为10进制的byte值是 3 ,这里的11表示的是一个2进制数
b[0] = Byte.parseByte(“11”, 3) = 4
表示 字符串11以3为基数表示为10进制的byte值是 4 ,这里的11表示的是一个3进制数
//另外这样使用byte是不会报错的:
byte=55;
//因为会自动把56当成byte类型去处理的了。



3.就是重点的int与Integer啦

 先吃份源码Integer解析套餐
public final class Integer extends Number implements Comparable<Integer> {

     public static final Class<Integer>  TYPE = (Class<Integer>) Class.getPrimitiveClass("int");//原始类型int的Class实例。
     //所有可能的将数字表示为字符串的字符集合做缓存。
     final static char[] digits = {
        '0' , '1' , '2' , '3' , '4' , '5' ,
        '6' , '7' , '8' , '9' , 'a' , 'b' ,
        'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
        'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
        'o' , 'p' , 'q' , 'r' , 's' , 't' ,
        'u' , 'v' , 'w' , 'x' , 'y' , 'z'
    };
    //两个构造器
     public Integer(int value) {
        this.value = value;
    }
    public Integer(String s) throws NumberFormatException {
        this.value = parseInt(s, 10);//涉及了String转换成int,一会仔细讨论这个。
    }
    //像上面Byte类型中解释的那样的方法,返回第二个参数所指定的进制数的第一个参数的字符串表示形式。处理各种进制的Integer.
    public static String toString(int i, int radix) {
        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)             
        radix = 10;//默认为10进制 
        /* Use the faster version */         
        if (radix == 10) {             
            return toString(i);         
        }
        char buf[] = new char[33];         
        boolean negative = (i < 0);         
        int charPos = 32;
        //统一转为负数去处理
        if (!negative) {             
            i = -i;         
        }
        while (i <= -radix) {             
            buf[charPos--] = digits[-(i % radix)];             
            i = i / radix;         
        }         
        buf[charPos] = digits[-i];
        if (negative) {             
            buf[--charPos] = '-';         
        }
        return new String(buf, charPos, (33 - charPos));     
    }
    //一会有事例代码演示这个,这个其实就是把int型包装成Integer然后再转化成String字符串
     public static String toString(int i) {
        if (i == Integer.MIN_VALUE)
            return "-2147483648";
        int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
        char[] buf = new char[size];
        getChars(i, size, buf);
        return new String(buf, true);
    }
    //与toString组合形成一方法去转换成字符串咯
    static void getChars(int i, int index, char[] buf) {
        int q, r;
        int charPos = index;
        char sign = 0;

        if (i < 0) { //如果i为负数,则设置i的符号字符为'-'。
            sign = '-';  //确定正负数
            i = -i;  //将负数转化为正数处理,提高效率 
        }

        // Generate two digits per iteration
        while (i >= 65536) { //如果i大于65536,则每一次都获取十位和个位上的数字对应的字符。将值判断大小后取每个数字,较大的数字一次取两位(大数字运算消耗大)
            q = i / 100;
        // really: r = i - (q * 100);
            r = i - ((q << 6) + (q << 5) + (q << 2)); //利用位运算,每次获得i的最后两位数,不断循环提取处理
            i = q;//重新赋值,准备下一次循环 
            buf [--charPos] = DigitOnes[r]; //存储r中在个位数集合中对应的字符
            buf [--charPos] = DigitTens[r]; //存储r中在十位数集合中对应的字符
        }

        // Fall thru to fast mode for smaller numbers
        // assert(i <= 65536, i);
        for (;;) { //i<65536的情况,小数字运算消耗较小,故一次只取一位
            q = (i * 52429) >>> (16+3);//52429/(2*19)约等于1,此处这样设计是为了提高精度
            r = i - ((q << 3) + (q << 1));  // r = i-(q*10) ... //每次获得i的最后两位数
            buf [--charPos] = digits [r];//取最后一位的数字  
            i = q;//重新赋值,准备下一次循环  
            if (i == 0) break;
        }
        if (sign != 0) {
            buf [--charPos] = sign; //设置符号
        }
    }
    //下面两个是用来确定字符串长度的。
    //定义sizeTable表示int中每个位数中最大的数,用于简便确定int数的长度。
    final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
                                      99999999, 999999999, Integer.MAX_VALUE };
    //使用上面的sizeTable定义来确定int数的字符串表示长度。           
    static int stringSize(int x) {
        for (int i=0; ; i++)
            if (x <= sizeTable[i])
                return i+1;
    }
    //炒鸡重要的方法啦!!parseInt(String s,int radix)使用第二个参数指定的基数,将字符串参数解析为有符号的整数。 parseInt(String s)只能将数字字符串转化十进制数
     public static int parseInt(String s, int radix)
                throws NumberFormatException
    {
        /*
         * WARNING: This method may be invoked early during VM initialization
         * before IntegerCache is initialized. Care must be taken to not use
         * the valueOf method.
         */

        if (s == null) {//参数检验,调用方法前检查参数的正确性。
            throw new NumberFormatException("null");
        }

        if (radix < Character.MIN_RADIX) {
            throw new NumberFormatException("radix " + radix +
                                            " less than Character.MIN_RADIX");
        }

        if (radix > Character.MAX_RADIX) {
            throw new NumberFormatException("radix " + radix +
                                            " greater than Character.MAX_RADIX");
        }

        int result = 0;
        boolean negative = false;
        int i = 0, len = s.length();//i表示当前遍历的s的位数
        int limit = -Integer.MAX_VALUE;//设置最小值为负的Integer的最大值
        int multmin;
        int digit;

        if (len > 0) {//如果字符串长度大于0,则进行转换
            char firstChar = s.charAt(0);//获取第一位字符
            if (firstChar < '0') { // Possible leading "+" or "-"
                if (firstChar == '-') {//判断是否为负数 
                    negative = true; 
                    limit = Integer.MIN_VALUE;//将限制转换为Integer的最小值,不能小于Integer的最小值  
                } else if (firstChar != '+')
                    throw NumberFormatException.forInputString(s);//第一个char不为+也不为-,则抛出异常  

                if (len == 1) // Cannot have lone "+" or "-"
                    throw NumberFormatException.forInputString(s);//若只有一个符号,则抛出异常
                i++;
            }
            multmin = limit / radix;//设定不同进制下的极限值  
            while (i < len) {//进行进制的转换
                // Accumulating negatively avoids surprises near MAX_VALUE
                digit = Character.digit(s.charAt(i++),radix);//将数字字符串转换成要求的进制数,使用工具类,每次遍历对一个字符进行操作转换  
                if (digit < 0) {
                    throw NumberFormatException.forInputString(s);
                }
                if (result < multmin) {
                    throw NumberFormatException.forInputString(s);
                }
                result *= radix;
                if (result < limit + digit) {
                    throw NumberFormatException.forInputString(s);
                }
                result -= digit;
            }
        } else {
            throw NumberFormatException.forInputString(s);
        }
        return negative ? result : -result;//根据符号返回正数还是负数
    }
    //看吧,我们经常用的parseInt只是个帮我们制定好10进制规则的静态方法
    public static int parseInt(String s) throws NumberFormatException {
        return parseInt(s,10);
    }
    //强大的内部类缓存机制吗,内部字符缓存类
    private static class IntegerCache {
        //缓存的下界,-128,不可变  
        static final int low = -128;
         //缓存上界,暂为null
        static final int high;
        static final Integer cache[];//利用数组来缓存
        //原理:初始化数组将一定范围的整数放到cache数组中,然后在调valueOf方法的时候首先判断范围然后从缓存数组中去抓取数据

        static {
            // high value may be configured by property
            // 缓存上届,可以通过JVM属性来配置
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            //获取,得到上界
            if (integerCacheHighPropValue != null) {
                try {
                    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);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;
            //获取Integer中所有能保存的数据,初始化缓存数组
            cache = new Integer[(high - low) + 1];
            int j = low;
            //缓存所有Integer的数据
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }
    //还有这个我们经常用的,官方也推荐使用这个方法去创建对象的
       public static Integer valueOf(int i) {
       //如果i在Integer缓存中,则直接取出
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
       //否则,直接创建一个实例
        return new Integer(i);
    }
}





使用Integer事例代码:

    //会打印出10这个字符串
    public static void main (String []args) {
        Integer i =null;
        i = Integer.valueOf(10);
        System.out.println(">>>>"+i.toString());
    }



public static void main(String[] args) {
        Integer a1 = 1;
        Integer a2 = 1;

        Integer b1 = 200;
        Integer b2 = 200;

        Integer c1 = Integer.valueOf(1);
//        Integer c2 = new Integer(1);      官方不推荐这种建对象的方法喔
        Integer c2 = Integer.valueOf(1);

        Integer d1 = Integer.valueOf(200);
        Integer d2 = Integer.valueOf(200);


        System.out.println("a1==a2?" + (a1 == a2));
        System.out.println("b1==b2?" + (b1 == b2));
        System.out.println("c1==c2?" + (c1 == c2));
        System.out.println("d1==d2?" + (d1 == d2));
    }




上面一段代码的运行结果就是我们要深思的东西啦,也是结合源码要懂的东西。
a1==a2? true 
b1==b2? false 
c1==c2? false 
d1==d2? false



第一个为什么是true呢,因为Integer的缓存机制嘛,刚刚我们看到的,缓存了[-128,127],这些可以直接取出。而剩余的为什么是false,因为他们都超过了缓存的那个范围,就建了个新对象咯。
至于short、float、double这类的包装类设计原理有的跟Integer差不多,但是比如Double,很难去阅读,感觉自己程度还不够,以后会补上。而Character这个包装类,,源码8000多行,我们就讨论它的一些基本知识吧。

4.Character的基本了解:

Character 类在对象中包装一个基本类型 char 的值。Character 类型的对象包含类型为 char 的单个字段。该类提供了几种方法,以确定字符的类别(小写字母,数字,等等),并将字符从大写转换成小写,从小写转换成大写。Character 类的方法和数据是通过 UnicodeData 文件中的信息定义的。至于Unicode 大家就百度了解下就好。

5.还有一份挺重要的源码,就是Long类:

public final class Long extends Number implements Comparable<Long> {
    @Native public static final long MIN_VALUE = 0x8000000000000000L;//最小值为2的63次方-1 
    @Native public static final long MAX_VALUE = 0x7fffffffffffffffL;//最大值为-2的63次方 
    public static final Class<Long>     TYPE = (Class<Long>) Class.getPrimitiveClass("long");
    //toString方法与Integer中的toString实现原理一样的。

    //转换成对应的进制的字符串表示
    public static String toUnsignedString(long i, int radix) {
        if (i >= 0)
            return toString(i, radix);
        else {
            switch (radix) {
            case 2:
                return toBinaryString(i);//将Long转为2进制  

            case 4:
                return toUnsignedString0(i, 2);//将Long转为4进制  

            case 8:
                return toOctalString(i);//将Long转为8进制  

            case 10:
                /*
                 * We can get the effect of an unsigned division by 10
                 * on a long value by first shifting right, yielding a
                 * positive value, and then dividing by 5.  This
                 * allows the last digit and preceding digits to be
                 * isolated more quickly than by an initial conversion
                 * to BigInteger.
                 */
                long quot = (i >>> 1) / 5;、//十进制嘛
                long rem = i - quot * 10;
                return toString(quot) + rem;

            case 16:
                return toHexString(i);

            case 32:
                return toUnsignedString0(i, 5);

            default:
                return toUnsignedBigInteger(i).toString(radix);
            }
        }
    }
    //返回一个BigInteger等于参数的无符号值
     private static BigInteger toUnsignedBigInteger(long i) {
        if (i >= 0L)
            return BigInteger.valueOf(i);
        else {
            int upper = (int) (i >>> 32);
            int lower = (int) i;

            // return (upper << 32) + lower
            return (BigInteger.valueOf(Integer.toUnsignedLong(upper))).shiftLeft(32).
                add(BigInteger.valueOf(Integer.toUnsignedLong(lower)));
        }
    }
    public static String toHexString(long i) {//将Long转为16进制  
        return toUnsignedString(i, 4);  
    }  
    public static String toOctalString(long i) {//将Long转为8进制  
        return toUnsignedString(i, 3);  
    }  
    public static String toBinaryString(long i) {//将Long转为2进制  
        return toUnsignedString(i, 1);  
    static int stringSize(long x) {//展示Long的字符串长度  
        long p = 10;  
        for (int i=1; i<19; i++) {//每次乘十进行比较  
            if (x < p)  
                return i;  
            p = 10*p;  
        }  
        return 19;  
    }  
    //这个也跟Integer的实现差不多。将字符串参数解析为有符号的整数。
    public static long parseLong(String s, int radix)
              throws NumberFormatException
    {
        if (s == null) {//参数检验
            throw new NumberFormatException("null");
        }

        if (radix < Character.MIN_RADIX) {
            throw new NumberFormatException("radix " + radix +
                                            " less than Character.MIN_RADIX");
        }
        if (radix > Character.MAX_RADIX) {
            throw new NumberFormatException("radix " + radix +
                                            " greater than Character.MAX_RADIX");
        }

        long result = 0;
        boolean negative = false;//这,,跟Integer基本一样的呀
        int i = 0, len = s.length();
        long limit = -Long.MAX_VALUE;
        long multmin;
        int digit;

        if (len > 0) {
            char firstChar = s.charAt(0);
            if (firstChar < '0') { // Possible leading "+" or "-"
                if (firstChar == '-') {
                    negative = true;
                    limit = Long.MIN_VALUE;
                } else if (firstChar != '+')
                    throw NumberFormatException.forInputString(s);

                if (len == 1) // Cannot have lone "+" or "-"
                    throw NumberFormatException.forInputString(s);
                i++;
            }
            multmin = limit / radix;
            while (i < len) {
                // Accumulating negatively avoids surprises near MAX_VALUE
                digit = Character.digit(s.charAt(i++),radix);
                if (digit < 0) {
                    throw NumberFormatException.forInputString(s);
                }
                if (result < multmin) {
                    throw NumberFormatException.forInputString(s);//转化为了负数进行计算,所以要用<号  
                }
                result *= radix;
                if (result < limit + digit) {
                    throw NumberFormatException.forInputString(s);
                }
                result -= digit;
            }
        } else {
            throw NumberFormatException.forInputString(s);
        }
        return negative ? result : -result;
    }
    public static long parseLong(String s) throws NumberFormatException {//默认转成10进制  
        return parseLong(s, 10);  
    }  
    //官方推荐的创建Long对象的方法啦
    public static Long valueOf(String s, int radix) throws NumberFormatException {  
        return Long.valueOf(parseLong(s, radix));  
    }  
    public static Long valueOf(String s) throws NumberFormatException  
    {  
        return Long.valueOf(parseLong(s, 10));  
    }
    //Long的默认缓存,-128~127,缓存模块与Integer相同  
     private static class LongCache {
        private LongCache(){}

        static final Long cache[] = new Long[-(-128) + 127 + 1];

        static {
            for(int i = 0; i < cache.length; i++)
                cache[i] = new Long(i - 128);
        }
    }
    public static Long valueOf(long l) {
        final int offset = 128;
        //在缓存范围内则直接使用咯
        if (l >= -128 && l <= 127) { // will cache
            return LongCache.cache[(int)l + offset];
        }
        return new Long(l);
    }
    public int hashCode() {//重写hashcode()方法,无符号右移32位后乘value本身  
        return (int)(value ^ (value >>> 32));  
    }  
    public boolean equals(Object obj) {  
        if (obj instanceof Long) {  
            return value == ((Long)obj).longValue();//比较的是value的地址值,所以在缓存范围内的相等,缓存范围外的不等(两个对象指向同一个Long除外)  
        }  
        return false;  
    }    
}



6.列出一下包装类的共性:

(1)带有基本值参数并创建包装类对象的构造函数.如可以利用Integer包装类创建对象,Integer obj=new Integer(145)
Integer obj=new Integer(145);
(2)带有字符串参数并创建包装类对象的构造函数.如new Integer(“-45.36”);
(3)可生成对象基本值的typeValue方法,如obj.intValue();
int num=obj.intValue();
(4)将字符串转换为基本值的 parseType方法,如Integer.parseInt(args[0]);
(5)因为有装进Map的几率,所以java设计了包装类里的哈希值,生成哈稀表代码的hashCode方法,如obj.hasCode();
(6)对同一个类的两个对象进行比较的equals()方法,如obj1.eauqls(obj2);
(7)生成字符串表示法的toString()方法,如obj.toString().
(8)自动装包/拆包大大方便了基本类型数据和它们包装类地使用。
自动装包:基本类型自动转为包装类。例如(int >> Integer)
自动拆包:包装类自动转为基本类型。例如(Integer >> int)

三、数据类型转换、装包拆包等一些小坑。

(1).类型转换:
基础:1.自动类型转换-系统支持把某种基本类型的值直接赋给另一种基本类型的变量。
规则:如下图,从左到右自动转换。这里写图片描述
2.强制类型转换-视图把表数范围大的类型转换为表数范围小的类型时,容器引起信息丢失。另:字符串不能直接转换为基本类型,但可通过基本类型对应的包装类实现转换成基本类型。如以下代码:
String a = "45";
int value=Integer.parseInt(a);



3.自动提升规则:当一个算术表达式中包含多个基本类型的值时,所有的byte类、short和char类型会被提示到int类型
(2)自动装包与拆包:自动装包/拆包大大方便了基本类型数据和它们包装类地使用。
自动装包:基本类型自动转为包装类.(int >> Integer)
自动拆包:包装类自动转为基本类型.(Integer >> int)
使用装包后,我们就可以用集合去存放基本类型啦。比如:Integer先自动转换为int进行加法运算,然后int再次转换为Integer。
int a = 3;
Collection c = new ArrayList();
c.add(a);//自动转换成Integer.自动装包
Integer b = new Integer(2);
c.add(b + 2);




好了,深入Java基础(一)——基本数据类型及其包装类讲完了。本博客是经过仔细其他类型的博客,结合源代码注释,并在这里做出进一步拓展以及写出自己的理解。另外,这个系列会逐步更新,也希望阅读更多源码,分享经验给大家。欢迎在下面指出错误,共同学习!!你的点赞是对我最好的支持!!

这个系列的文章因为涉及很多源码,所以会根据网友们的反应以及我的学习深入去补充。希望大家一起来讨论学习。

转载请注明:【JackFrost的博客】

更多内容,可以访问JackFrost的博客

Java基础——基本数据类型及包装类 Java是一种面向对象的语言,有时候需要对象操作才比较方便,所有的基本数据类型都有其对应的包装类。基本数据类型和其包装类之间可以直接赋值,会自动装箱和拆箱。查看运行的汇编指令,发现自动装箱其实调用的是Integer类中的valueOf方法,自动拆箱调用的是Integer类中的intValue方法。所以我们也可以调用包装类中的类似这两个方法来转换基本数类型和包装类型。 阅读详情

相关推荐

ZYQN7000系列VxWorks驱动开发:VxWorks系统移植

文章目录ZYQN7000驱动开发:VxWorks系统移植1.硬件环境2.编译vsb和vip工程2.1修改设备树文件2.2添加调试打印组件3.选择uboot来启动VxWorks内核4.尝试在开发板上启动内核4.1 拷贝镜像和设备树至SD卡4.2开发板上电4.2.1 uboot成功启动4.2.2 启动VxWorks5.添加shell和cmd组件 ZYQN7000驱动开发:VxWorks系统移植 1.硬件环境 正点原子领航者开发板 2.编译vsb和vip工程 vsb和vip工程的编译过程可以参考之前的文章,htt

明故宫的记忆 5504

怎样讲JAVA的数据类型?

1.基本概念: 基本数据类型分为两大类,第一类:基本数据类型,第二类:引用数据类型,基本数据类型包括四小类:整型、浮点型、字节型和布尔型, 引用数据类型包括三小类,第一:类、第二:接口、第三:数组, 整型基本数据类型又分为四个小类:整型的四个小类根据它们存储的数据的大小和内存当中占据的多少位, 以次从小往大分为:byte类型、short类型、int类型、long类型,java之所以把整型分为4个小类,其主要目的是为了节约内存开销, 你想要用什么类型,

婷er的博客 888

Innovus 安装全过程

【代码】Innovus 安装全过程。

lmyynlbcy的博客 5532

VMware Ubuntu虚拟机扩容 value out of range 问题

近期扩容发现了一个小问题,在新建磁盘分区时,提示“value out of range”,明明没有超过范围,却提示超过了。原来没注意是指定“起始扇区”位置--first sector(一般回车选默认)。各位注意了,指定分区的“末尾扇区”位置--last sector(+你想要的分区大小,如+28G),然后”(last sector-first sector)*扇区大小“才是这个磁盘分区的大小。最...

liuxh优快云的博客 1万+

Kong API Gateway 配置与深入

Kong是一个开源的、高性能的API网关,提供了一种简单易用的服务间路由、流量管理和安全防护方案,其最初起源于Nginx Inc.,但后迁移至Apache Software Foundation。Kong支持RESTful、GraphQL、TCP/UDP等协议,可与AWS Lambda、Azure Functions、Google Cloud Functions等云函数平台集成。其主要功能包括:服务发现与负载均衡、请求代理、身份认证与授权、缓存、日志记录、监控指标、灰度发布、多种插件等。

AI天才研究院 2281

【人工智能之深度学习】21. 自动驾驶感知实战:YOLOv4复杂天气优化方案(BDD100K全代码+效果对比)

摘要:自动驾驶摄像头在雨雾天气下易受图像模糊、目标遮挡影响,导致YOLOv4检测精度骤降。本文基于BDD100K公开数据集(含多天气场景),设计三阶段优化方案:1)物理建模生成雨雾效果(雨滴线条+大气散射模型),将恶劣天气样本占比从20%提升至40%;2)在YOLOv4颈部嵌入CBAM注意力机制,强化模糊区域特征提取;3)L1剪枝(30%)+TensorRT量化实现轻量化。需特别说明:本文为教学虚拟案例,不可直接用于车载部署,实际落地需结合多传感器融合与ISO 26262认证。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 1681

java基本数据类型_安卓APP开发 | 简单学Java从编程入门开始-包装类

Java语言8种基本数据类型能够适应对象中属性的封装,但是这些基本数据不具备对象的特性,不能满足一些比较特殊的数据转换,比如double类型转换成int类型。并且,Java中很多类的方法参数类型为为Object类型,其接收的参数也必须是对象。如果8种基本数据类型要转变成Object类型,必须要用到对应的包装类。一. 包装类的定义基本数据对应的包装类在Object里面的继承关系所谓的包装类,是指fi...

weixin_39832829的博客 134

【第1章>第8节】FNN模糊神经网络的理论学习与MATLAB仿真

模糊神经网络(FNN,Fuzzy Neural Network)是将模糊逻辑与神经网络相结合的一种智能算法,它融合了模糊逻辑善于处理不确定性和神经网络的自学习、自适应能力。

FPGA/MATLAB学习教程/源码/项目合作开发 388

Java 包装类和基本类型

Java 语言是一个面向对象的语言,但是 Java 中定义的基本数据类型却是不面向对象的。 有时候我们需要对对象进行操作,有时候我们却需要对基本数据类型进行操作。 基本概念 从 Java 5 开始增加了自动装箱和拆箱。 在基本值和String对象间相互转换,在基本值和String对象之间按不同基数转换,如二进制、八进制和十六进制。 按照 Java 的命名规范,属于对象的数据类型,通常都是以大写字母开头的,基础数据类型是小写字母开头的。 包装类 如果涉及到从基本数据类型到对象数据类型

HONEY MOOSE 273

《QT+PCL 第一章》:点云读取显示

点云读取显示一、核心代码二、QT设置三、效果展示 一、核心代码 二、QT设置 三、效果展示

阁楼 1万+

YOLOv11在视频流中的时序建模改进-(加入ConvLSTM或Transformer捕捉帧间关联)

本文提出了一种结合ConvLSTM和Transformer的改进YOLOv11算法,用于增强视频目标检测的时序建模能力。针对视频检测中运动模糊、遮挡等挑战,研究分析了ConvLSTM的局部时空特征建模和Transformer的全局注意力机制之间的互补性。通过数学公式详细阐述了ConvLSTM的门控机制和Transformer的自注意力计算原理,并提出分层融合策略:底层使用ConvLSTM处理高分辨率特征捕捉局部运动,高层应用Transformer建立全局时空关联。改进方案在YOLOv11架构中插入时序增强模

本博客聚焦 YOLOv11 全流程落地,涵盖架构优化、数据集处理、训练技巧与多场景部署,兼及国产数据库、Java 开发与 AI 模型应用,内容兼顾理论与工程实践,为开发者提供系统干货,助力高效提升技术能力。 680

基本数据类型的包装类

byte Byte short short int Integer long Long boolean Boolean float Float double Double char Character 基本数据类型对象包装类的最常见作用, 就是用于基本数据类型和字符串类型之间做转换 基本数据类型转成字符串。 基本数据类型+"" 基本数据类型.toString(基本数据类型值); 如: Integ...

qq_37860317的博客 163

【安全机制分析案例】从PDF预览页面提取原始PDF文件的方法原理与实践 篇二:基于致远互联(Seeyon)封装的SuwellLightRead技术

该HTML代码片段展示了致远OA协同办公系统的前端页面结构,包含多个CSS样式表和JavaScript文件的引用。页面设置了IE兼容模式,加载了全局环境变量、UI组件库和公告模块相关资源。代码中定义了系统路径、静态资源后缀等全局变量,并包含公告查看功能的相关配置参数。页面还引用了水印、文档处理、即时通讯等功能的JS文件,并设置了文件下载框架。整体呈现了一个典型的OA系统前端实现方案,包含浏览器兼容处理、资源加载和功能模块初始化等逻辑。

生活在别处 2072

Java基本数据类型及其包装类

Java基本数据类型及其包装类 正文开始@Assassin 目录Java基本数据类型及其包装类1. 基本类型包装类概述:1.1 基本数据类型和包装类型的区别:1.2 各包装类的一些基本的属性:2. 基本数据类型包装类应用:2.1 基本类型 → 字符串:2.2 字符串 → 基本类型:3. Integer类:3.1 Integer类概述:3.2 构造方法:3.3 int类型和String类型的相互转换:3.4 常用的基本进制转换:3.5 十进制转换成其他进制:3.6 其他进制到十进制:3.7 自动拆装箱:4.

NingHai's blog 829

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Java 中基本数据类型的包装类详解

在 Java 中,我们经常会使用基本数据类型,例如 int, double, boolean 等。这些类型直接存储在内存中,并以二进制形式表示。然而,有时我们需要将这些基本数据类型转换为对象,以便能够使用对象的方法和特性。这就是包装类发挥作用的地方。

weixin_64178283的博客 1570

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Java中的基础数据类型及其包装类

在 Java 中,​​基础数据类型(Primitive Data Types)​​ 是语言内置的基本数据类型,它们不是对象,而是直接存储值的数据类型。Java 的基础数据类型共有 ​​8 种​​,分为 ​​4 类​​:​​整数类型​​、​​浮点类型​​、​​字符类型​​ 和 ​​布尔类型​​。类别数据类型位数(bits)字节(bytes)取值范围默认值​​整数型​​byte81-128 ~ 1270short1620int324。

qq_57019146的博客 917

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

基本数据类型及其对应的包装类存在的意义

Java--基本数据类型及其对应的包装类存在的意义八种基本数据类型1.整数2.浮点数3.字符型4.布尔型数据类型之间的相互转换看到这儿很简单,我感觉每个人都会。BUT请继续向下看基本数据类型为什么存在?意义存储数据加载八种基本数据类型的包装类1.对应表2.包装类型为什么存在?3.特点两者比较 八种基本数据类型 1.整数 byte 字节型1个字节 8位,最大存储数据量是255,存放的数据范围是...

weixin_44684812的博客 1672

Java中的包装类与基本数据类型详解(进阶一)

①首先包装类是类,是引用类型②是为了方便拓展使用基本数据类型而进行封装的类。

baomingshu的博客 1481

Java8种基本数据类型及其包装类

一、Java四大数据类型分类 1、整型 byte 、short 、int 、long 2、浮点型 float 、 double 3、字符型 char 4、布尔型 boolean 二、八种基本数据类型 三、8种基本类型及其包装类 Java为这8种基本数据类型,提供了对应的包装类。每个包装类都对相应的基础类型有操作方法,也有几种类型的转换。大家可以对应api文档去学习,这里就不详细说明了。 1、byte和包装类Byte 数据存储是以”字节“(Byte)为单位的,一个字节有8”位“。相当于8个盒子,但

weixin_46511008的博客 7980

Java基础——基本数据类型及其包装类

文章目录基本数据类型包装数据类型区别自动装箱和拆箱原理 基本数据类型 Java中共有八中基本数据类型,分别为: byte short int long float double char boolean 包装数据类型 基本数据类型 大小 默认值 包装数据类型 byte 8 bit 0 Byte short 16 bit 0 Short int 32 bit 0 Inte...

weixin_40693633的博客 885

java的包装类及其转换

java的包装类包装类介绍包装类与基本数据类型、字符串之间的转换包装类与基本数据类型之间的转换基本数据类型转换成包装类包装类转换成基本数据类型自动装箱和自动拆箱包装类和基本数据类型同String类之间的转换基本数据类型、包装类转换成String类型String类型转换成基本数据类型或包装类 文章内容选自尚硅谷 包装类介绍 java当中的基本数据类型并不是类的一种,没有方法,也没有属性,而java是面向对象的编程,如果把基本数据类型也当作类的一种,再调用类的方法和属性,则java就能充分体现面向对象的编程思想

Meloneating的博客 1510

【Java基础篇】基本数据类型和包装类

首先我谈一下自己的理解,首先Java是一门面向对象的语言,可以说一切皆是对象。1、比如在集合操作中,能够操作和存储的都是对象,无法使用基本数据类型(在jvm自动拆装箱的前提下,使用包装类的使用方式更灵活了)。2、其次从业务理解上,比如定义一个Sutdent类,一个int型的score属性和一个Integer的score属性,Integer即可为null也可为0,但是int只能为空,要注意,成绩为空和成绩为0是截然不同的意思!因此在表达含义上使用包装类同样更加便捷。By the way!!

m0_56666971的博客 1005
上一篇: Android-多列表的项目(Rxjava+Rtrofit+Recyclerview+Glide+Adapter封装)之(二)网络层的封装
下一篇: SAP 系统参数设置 RZ10 RZ11
Footloose_
博客等级 码龄10年 254粉丝 11原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值