进一步理解Java中的基本数据类型以及对应的包装类

版权声明:本文为博主原创,转载请注明出处。 https://blog.csdn.net/u011848397/article/details/80145650


自述
Java中的基本数据类型可以说是相当基础的一部分了,在日常开发中经常用到,但我们平时却不会过于深究。
第一部分,重新回顾一遍基本数据类型相关的内容,对与比较模糊的地方着重的总结了一下。
第二部分,通过JDK文档,结合源码,深入了解各个包装类。


基本数据类型

基本特性

4种整数型:

数据类型 二进制位数 包装类 默认值 可表示范围
byte 8 Byte 0 -128~127
short 16 Short 0 -32768~32767
int 32 Integer 0 -2147483648~2147483647
long 64 Long 0L 263 ~ 263


2种浮点型

数据类型 二进制位数 包装类 默认值 可表示范围
float 32 Float 0.0f -2147483648~2147483647
double 64 Double 0.0d 263 ~ 263


1种字符型

数据类型 二进制位数 包装类 默认值 可表示范围
char 16 Character ‘/uoooo’(null) 0~65535


1种布尔型

数据类型 二进制位数 包装类 默认值 可表示范围
boolean 1 Boolean false true/false

初始化的一些细节

对于像int i = 1这样的基本操作我就不解释了,这里主要记录一些使用比较少,容易忽略的内容:

尾缀

尾缀用三种,分别是:long->l(L)、float->f(F)、double->d(D),大小写不敏感,但通常我们会将long的尾缀用大小L,其余两个用小写,因为小写的字母”l”跟数字”1”容易混淆。

字面量和初始化

  • 如果一个字面量是一个整型,JVM会默认为int类型
  • 如果一个字面量是一个浮点型,JVM会默认double类型。

所以如果声明float f = 1.0会报错cannot convert from double to float

强制类型转换

  这部分相信大家都有了解,进行转换时,表示范围如果扩大了,则可自动转换;如果缩小了,则需要强制类型转换:

 - boolean型和其它基本数据类型之间不能相互转换; 
 - byte型可以转换为short、int、、long、float和double; 
 - short可转换为int、long、float和double; 
 - char可转换为int、long、float和double; 
 - int可转换为long、float和double; 
 - long可转换为float和double; 
 - float可转换为double; 

Console控制台打印默认值

我们可以通过声明静态变量(或全局变量)的方式查看默认值。

public class Simple {
    static byte b;
    static short s;
    static int i;
    static long l;
    static float f;
    static double d;
    static char c;
    static boolean bln;
    public static void main(String[] args) {
        System.out.println("byte:\""+b+"\"");
        System.out.println("short:\""+s+"\"");
        System.out.println("int:\""+i+"\"");
        System.out.println("long:\""+l+"\"");
        System.out.println("float:\""+f+"\"");
        System.out.println("double:\""+d+"\"");
        System.out.println("char:\""+c+"\"");
        System.out.println("boolean:\""+bln+"\"");
    }
}

结果:

byte:"0"
short:"0"
int:"0"
long:"0"
float:"0.0"
double:"0.0"
char:" "
boolean:"false"

这里需要注意的是:

  • 后缀是不会打印出来的。
  • char的默认值,打印出来的是一个空白符号,而不是null或者其他(空格的Unicode为’\u0020’)。

char类型

char类型时我们日常开发中比较少接触的一种数据类型,所以这里单独拿出来讲一讲。

  • char类型储存的是一个整型字面量,范围从0~65535;我们可以从char c = 'a'+'a';//cannot convert from int to char得到验证。
  • char的赋值方式有2种,一种是通过整型字面量赋值char c = 97,另一种是通过字符型字面量赋值char c = 'a'。(Java中,单引号”用来引用单个字符,双引号”“用来引用字符串)
  • 当打印char到控制台的时候,因为字符串拼接等原因,会出现比较复杂的情况:
char c1 = 'a';
char c2 = 97;
//因为该方法的内部实现是将根据
System.out.println(c1);             //a
System.out.println(c2);             //a

System.out.println(c1+c2);          //194
System.out.println(c1+97);          //194
System.out.println('a'+'a');        //194

我们先看看println的源码:

public void println(char x) {
       synchronized (this) {
           print(x);
           newLine();
       }
   }

   //再看看print(x)
   public void print(char c) {
       write(String.valueOf(c));
   }

我们可以得出结论:
1. 对于传入的单个char类型,最终会调用String.valueOf方法,将其转换成一个String类型的变量然后输出到控制台。
2. 当两个char类型的变量相加时,由于char类型储存的是一个整型字面量,所以相当于两个int相加,所以时以int类型作为参数传入println方法的。

但当情况更加复杂时,结果又会如何?

System.out.println(c1+c2+"");       //194
System.out.println(""+c1+c2);       //aa
System.out.println(c1+""+c2);       //aa
System.out.println(c1+c2+""+c1+c2);      //194aa

  这次出现的结果很有意思,前半部分相当于两个char类型的变量相加,是个int类型,后半部分则是单个的char转换为String类型后拼接而来。
  这里涉及了字符串拼接,与JVM有关(本人JVM方面刚开始看,还不够了解,如果有大神出现的话,请纠正),这里试着解释一下,姑且一看吧:

  • 字符串拼接是有先后顺序的,按照+号的出现顺序依次拼接。
  • 第一句的c1+c2并不是字符串拼接,而是int类型相加;之后的+号才是字符串拼接,此时先将int转化为了String,然后空字符串进行拼接。(ps:+和+=是Java中唯二两个重载过的操作符)
  • 第二句中,c1+""是将char类型转化为String类型,然后与空字符串拼接;然后再转换后一个char为String,并再次拼接。
  • 后面三、四句可以按照同样的方式进行理解。
  • 不管是int还是char(其他基本类型也一样),转为String类型时,都相当于通过String.valueOf得到一个新的字符串。

包装类

概述

Java中一切都是对象,但是为了编程的方便还是引入了基本数据类型。同时为了能够将这些基本数据类型当成对象操作,Java为每一个基本数据类型都引入了对应的包装类(wrapper class)。

基本类型 二进制位数 包装类 基本类型 二进制位数 包装类
byte 8 Byte boolean 1 Boolean
short 16 Short char 16 Character
int 32 Integer float 32 Float
long 64 Long double 64 Double


注意:Java中的基本数据类型只有以上8个,除了基本类型(primitive type),剩下的都是引用类型(reference type),所以包装类也属于引用类型。

自动装箱/拆箱

从Java5开始,引入泛型的概念,并同时引入了自动装箱/拆箱机制。引入该机制的目的是为了简化开发者的操作,使二者可以相互转换。

举个栗子:
首先我们要知道,对于一个整型字面量,java是会将其视为int类型;

// 声明并初始化一个基本数据类型
int i = 1;
// 声明并初始化一个对象
Integer integer = new Integer(2);

// 自动装箱机制
Integer integer2 = 2;

当然这种例子,在我们日常开发中,通常是不会出现的。我们一般遇到的开发场景是什么呢?
集合(比如List、Map、Set)
下面是我们日常开发中最为常见的,自动装箱的应用场景,以List为例:

List<Integer> list = new ArrayList<>();
// 如果没有自动装箱
list.add(new Integer(1));
// 有自动装箱
list.add(2);

自动拆箱跟自动装箱相反,接上面:

// 如果没有自动拆箱
Integer integer = list.get(0);
for(Integer integer2 : list){
    ...
}
// 有自动拆箱
int i = list.get(0);
for(int t : list){
    ...
}

Boolean

Character

Byte

Short

Integer

Long

Float

Double

猜你喜欢

转载自blog.csdn.net/u011848397/article/details/80145650
今日推荐