冬天可以种植黑心菊吗?

小说:冬天可以种植黑心菊吗?作者:卓徒更新时间:2019-04-20字数:79477

  上一篇博客我们介绍了 java.lang 包下的 Object 类,那么本篇博客接着介绍该包下的另一个类 Integer。在前面 浅谈 Integer 类 博客中我们主要介绍了 Integer 类 和 int 基本数据类型的关系,本篇博客是从源码层次详细介绍 Integer 的实现。

1、Integer 的声明

public final class Integer extends Number implements Comparable<Integer>{}

  Integer 是用 final 声明的常量类,不能被任何类所继承。并且 Integer 类继承了 Number 类和实现了 Comparable 接口。 Number 类是一个抽象类,8中基本数据类型的包装类除了Character 和 Boolean 没有继承该类外,剩下的都继承了 Number 类,该类的方法用于各种数据类型的转换。Comparable 接口就一个  compareTo 方法,用于元素之间的大小比较,下面会对这些方法详细展开介绍。

2、Integer 的主要属性

  

  

  int 类型在 Java 中是占据 4 个字节,所以其可以表示大小的范围是 -2 31——2 31 -1即 -2147483648——2147483647,我们在用 int 表示数值时一定不要超出这个范围了。

3、构造方法 Integer(int)    Integer(String)

  对于第一个构造方法 Integer(int),源码如下,这没什么好说的。

1     public Integer(int var1) {
2         this.value = var1;
3     }
View Code

  对于第二个构造方法 Integer(String) 就是将我们输入的字符串数据转换成整型数据。

  首先我们必须要知道能转换成整数的字符串必须分为两个部分:第一位必须是"+"或者"-",剩下的必须是 0-9 和 a-z 字符

 1 public Integer(String s) throws NumberFormatException {
 2     this.value = parseInt(s, 10);//首先调用parseInt(s,10)方法,其中s表示我们需要转换的字符串,10表示以十进制输出,默认也是10进制
 3 }
 4 
 5 public static int parseInt(String s, int radix) throws NumberFormatException{
 6     //如果转换的字符串如果为null,直接抛出空指针异常
 7     if (s == null) {
 8         throw new NumberFormatException("null");
 9     }
10     //如果转换的radix(默认是10)<2 则抛出数字格式异常,因为进制最小是 2 进制
11     if (radix < Character.MIN_RADIX) {
12         throw new NumberFormatException("radix " + radix +
13                                         " less than Character.MIN_RADIX");
14     }
15     //如果转换的radix(默认是10)>36 则抛出数字格式异常,因为0到9一共10位,a到z一共26位,所以一共36位
16     //也就是最高只能有36进制数
17     if (radix > Character.MAX_RADIX) {
18         throw new NumberFormatException("radix " + radix +
19                                         " greater than Character.MAX_RADIX");
20     }
21     int result = 0;
22     boolean negative = false;
23     int i = 0, len = s.length();//len是待转换字符串的长度
24     int limit = -Integer.MAX_VALUE;//limit = -2147483647
25     int multmin;
26     int digit;
27     //如果待转换字符串长度大于 0 
28     if (len > 0) {
29         char firstChar = s.charAt(0);//获取待转换字符串的第一个字符
30         //这里主要用来判断第一个字符是"+"或者"-",因为这两个字符的 ASCII码都小于字符"0"
31         if (firstChar < "0") {  
32             if (firstChar == "-") {//如果第一个字符是"-"
33                 negative = true;
34                 limit = Integer.MIN_VALUE;
35             } else if (firstChar != "+")//如果第一个字符是不是 "+",直接抛出异常
36                 throw NumberFormatException.forInputString(s);
37 
38             if (len == 1) //待转换字符长度是1,不能是单独的"+"或者"-",否则抛出异常 
39                 throw NumberFormatException.forInputString(s);
40             i++;
41         }
42         multmin = limit / radix;
43         //通过不断循环,将字符串除掉第一个字符之后,根据进制不断相乘在相加得到一个正整数
44         //比如 parseInt("2abc",16) = 2*16的3次方+10*16的2次方+11*16+12*1 
45         //parseInt("123",10) = 1*10的2次方+2*10+3*1 
46         while (i < len) {
47             digit = Character.digit(s.charAt(i++),radix);
48             if (digit < 0) {
49                 throw NumberFormatException.forInputString(s);
50             }
51             if (result < multmin) {
52                 throw NumberFormatException.forInputString(s);
53             }
54             result *= radix;
55             if (result < limit + digit) {
56                 throw NumberFormatException.forInputString(s);
57             }
58             result -= digit;
59         }
60     } else {//如果待转换字符串长度小于等于0,直接抛出异常
61         throw NumberFormatException.forInputString(s);
62     }
63     //根据第一个字符得到的正负号,在结果前面加上符号
64     return negative ? result : -result;
65 }
View Code

 4、toString()  toString(int i)   toString(int i, int radix)

  这三个方法重载,能返回一个整型数据所表示的字符串形式,其中最后一个方法 toString(int,int) 第二个参数是表示的进制数。

public String toString() {
    return toString(value);
}

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);
}
View Code

  toString(int) 方法内部调用了 stringSize() 和 getChars() 方法,stringSize() 它是用来计算参数 i 的位数也就是转成字符串之后的字符串的长度,内部结合一个已经初始化好的int类型的数组sizeTable来完成这个计算。

    final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
                                      99999999, 999999999, Integer.MAX_VALUE };

    // Requires positive x
    static int stringSize(int x) {
        for (int i=0; ; i++)
            if (x <= sizeTable[i])
                return i+1;
    }
View Code

  实现的形式很巧妙。注意负数包含符号位,所以对于负数的位数是 stringSize(-i) + 1。

  再看 getChars 方法:

 1    static void getChars(int i, int index, char[] buf) {
 2         int q, r;
 3         int charPos = index;
 4         char sign = 0;
 5 
 6         if (i < 0) {
 7             sign = "-";
 8             i = -i;
 9         }
10 
11         // Generate two digits per iteration
12         while (i >= 65536) {
13             q = i / 100;
14         // really: r = i - (q * 100);
15             r = i - ((q << 6) + (q << 5) + (q << 2));
16             i = q;
17             buf [--charPos] = DigitOnes[r];
18             buf [--charPos] = DigitTens[r];
19         }
20 
21         // Fall thru to fast mode for smaller numbers
22         // assert(i <= 65536, i);
23         for (;;) {
24             q = (i * 52429) >>> (16+3);
25             r = i - ((q << 3) + (q << 1));  // r = i-(q*10) ...
26             buf [--charPos] = digits [r];
27             i = q;
28             if (i == 0) break;
29         }
30         if (sign != 0) {
31             buf [--charPos] = sign;
32         }
33     }
View Code

  i:被初始化的数字,

  index:这个数字的长度(包含了负数的符号“-”),

  buf:字符串的容器-一个char型数组。

  第一个if判断,如果i<0,sign记下它的符号“-”,同时将i转成整数。下面所有的操作也就只针对整数了,最后在判断sign如果不等于零将 sign 你的值放在char数组的首位buf [--charPos] = sign;。  

5、自动拆箱和装箱

  自动拆箱和自动装箱是 JDK1.5 以后才有的功能,也就是java当中众多的语法糖之一,它的执行是在编译期,会根据代码的语法,在生成class文件的时候,决定是否进行拆箱和装箱动作。

  ①、自动装箱

  我们知道一般创建一个类的对象需要通过 new 关键字,比如:

Object obj = new Object();

  但是实际上,对于 Integer 类,我们却可以直接这样使用:

Integer a = 128;

  为什么可以这样,通过反编译工具,我们可以看到,生成的class文件是:

Integer a = Integer.valueOf(128);

  我们可以看看 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);
}
View Code

  其实最后返回的也是通过new Integer() 产生的对象,但是这里要注意前面的一段代码,当i的值 -128 <= i <= 127 返回的是缓存类中的对象,并没有重新创建一个新的对象,这在通过 equals 进行比较的时候我们要注意。

  这就是基本数据类型的自动装箱,128是基本数据类型,然后被解析成Integer类。

  ②、自动拆箱

  我们将 Integer 类表示的数据赋值给基本数据类型int,就执行了自动拆箱。

1 Integer a = new Integer(128);
2 int m = a;

  反编译生成的class文件:

1 Integer a = new Integer(128);
2 int m = a.intValue();

  简单来讲:自动装箱就是Integer.valueOf(int i);自动拆箱就是 i.intValue();关于拆箱和装箱的详细介绍可以看我这篇博客。

6、equals(Object obj)方法

public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
}

  这个方法很简单,先通过 instanceof 关键字判断两个比较对象的关系,然后将对象强转为 Integer,在通过自动拆箱,转换成两个基本数据类 int,然后通过 == 比较。

7、hashCode() 方法

1     public int hashCode() {
2         return value;
3     }

  Integer 类的hashCode 方法也比较简单,直接返回其 int 类型的数据。

8、parseInt(String s) 和  parseInt(String s, int radix) 方法

  前面通过 toString(int i) 可以将整型数据转换成字符串类型输出,这里通过 parseInt(String s) 能将字符串转换成整型输出。

  这两个方法我们在介绍 构造函数 Integer(String s) 时已经详细讲解了。

9、compareTo(Integer anotherInteger) 和 compare(int x, int y) 方法

1     public int compareTo(Integer anotherInteger) {
2         return compare(this.value, anotherInteger.value);
3     }
View Code

  compareTo 方法内部直接调用 compare 方法:

1     public static int compare(int x, int y) {
2         return (x < y) ? -1 : ((x == y) ? 0 : 1);
3     }
View Code

  如果 x < y 返回 -1

  如果 x == y 返回 0

  如果 x > y 返回 1

1 System.out.println(Integer.compare(1, 2));//-1
2 System.out.println(Integer.compare(1, 1));//0
3 System.out.println(Integer.compare(1, 0));//1
View Code

  那么基本上 Integer 类的主要方法就介绍这么多了,后面如果有比较重要的,会再进行更新。

 

参考文档:https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html

 

当前文章:http://cnsdbtzg.com/news/20190196435.html

发布时间:2019-04-20 16:28:04

哪里出售紫荆花树? 广东有种植黄金柳的基地吗? 高中低档货源充足,月季树批发当然来全国最大的月季树专业市场 发现了国内大型的雪松种植基地,有图有真相 新疆红王子锦带小苗去哪买? 移栽红瑞木最佳月份是什么时候? 4米高紫荆价格什么地方便宜? 11月份可以栽植玉簪吗? 哪里有扶芳藤绿化种植基地? 云南可以种植红玉兰吗?

54552 27322 14735 57690 92729 42189 31417 35962 47059 21620 87929 44223 15571 58400 20356 43846 30705 17036 93421 21596 36778 32298 86698

我要说两句: (0人参与)

发布