一、数据类型

1、分类

Java中的数据类型分两大类分别是基本类型引用数据类型

注意:字符串不属于基本数据类型,属于引用数据类型;字符属于基本数据类型。

2、基本数据类型的字节数及表示范围


(1)整型变量默认为 int 类型

byte a = 100;
short s = 1000;
int a = 100000;
long a = 100000L;   // 错误写法:long a = 100000;

因为整型变量默认为 int 类型,所以上述代码中的 100,1000,100000 都默认是 int 型,int 型会隐含强制转换为低级别的 byte 和 short,但只能显式强制转换为 long 型,所以必须写为 long a = 100000L; 或者 long a = (long)100000;

(2)浮点数的默认类型为 double 类型

float f1 = 234.5f;
double d1 = 123.4;

3、基本数据类型对应的包装类

出现原因:

Java 是面向对象的语言,但是为了便于开发者的使用,Java 中却沿用了 C 语言的基本数据类型,在进行基本的数据计算时,开发者可以直接使用基础类。但是基本数据类型是不具备对象的特征的,不能调用方法,而且基本数据类型不能存入集合中,所以就需要将基础数据类型实例封装为 Java 对象,使其具有了对象的属性和方法。而且原始类型不能为 null,但包装类可以 为null。包装类也可用于实现多态性。


(1)基本类型与包装类的区别

①存储位置不同:
基本数据类型直接将值放在栈中
包装类型是把对象放在堆中,然后通过对象的引用来调用他们
②初始值不同:
int的初始值为 0 、 boolean的初始值为false ;
包装类型的初始值为null
③使用方式不同:
基本数据类型直接赋值使用就好;
在集合如 coolectionMap 中只能使用包装类型

(2)基本类型与包装类的相互转换

① 手动转换

● 基本数据类型 → 包装类:

通过对应包装类的构造方法实现,除了Character外,其他包装类都可以传入一个字符串参数构建包装类对象。

● 包装类 → 基本数据类型

通过包装类的实例方法 xxxValue() 实现; // xxx表示包装类对应的基本数据类型

② 自动装箱&自动拆箱(jdk1.5以后)

基本类型添加到集合中时,进行自动装箱
包装类型在涉及到运算的时候,“加,减,乘, 除” 以及 “比较 equals,compareTo”,进行自动拆箱

4、数据在内存中的存储位置

(1)static final 修饰的常量

存放在常量池中,JDK1.8以前在方法区,JDK1.8及以后在堆中。

(2)方法中声明的局部变量

在方法中声明的变量,即该变量是局部变量,每当程序调用方法时,系统都会为该方法建立一个方法栈,其所在方法中声明的变量就放在方法栈中,当方法结束系统会释放方法栈,其对应在该方法中声明的变量随着栈的销毁而结束。

① 当声明的是基本类型的变量时,其变量名及值(变量名及值是两个概念)是放在方法栈中
② 当声明的是引用变量时,所声明的变量(该变量实际上是在方法中存储的是内存地址值)是放在方法的栈中,该变量所指向的对象是放在堆内存中

(3)类中声明的成员变量

● 在类中声明的没有用 static 修饰的变量是成员变量,也叫全局变量,放在堆中的(因为全局变量不会随着某个方法执行结束而销毁)。

① 当声明的是基本类型的变量时,其变量名及其值放在堆内存中
② 当声明的是引用类型时,其声明的变量仍然会存储一个内存地址值,该内存地址值指向所引用的对象,引用变量名和对应的对象仍然存储在相应的堆中

● 类中的成员变量用 static 修饰是静态成员变量,存储在方法区

二、常数

1、十六进制

十六进制表示必须以 0x 或 0X 开头,如0xff、0X9A。

2、八进制

八进制表示必须以 0 开头,如0123、034。

3、十进制

(1)整数

在java中,整数常量默认是 int 类型

① long 类型

● 若数值没有超出 int 范围,可以直接赋值给 long 类型,发生自动向上转换( int —> long)。

long num = 123;  // ok,注意123默认是int类型,发生自动转换

若数值超出 int 范围但没有超出 long 范围,赋值给long类型必须用 L 或 l 修饰不会发生自动转换

long num = 99999999999999;  //  error,99999999999999默认是int类型,超出了int类型,所以还没赋值就出错了
long num = 99999999999999L; //  ok,99999999999999L被L修饰,不能默认是int类型,已经是long类型,可以直接赋值

② byte、short 和 char 类型( int —> byte、short 和、char 需要向下转换 )

● 若数值没有超出 byte、short 和 char 类型的范围,可以直接赋值给该类型。

 byte d = 135 ;       //  errorbyte d = 3 + 5 ;     //  okbyte d = a +b ;       //  error,a 和 b 都是变量。编译器在编译期间无法得知变量相加的值

若数值超出byte、short 和 char 类型范围,赋值给该类型必须强制转换

byte d = 135 ;       //  error
byte d = (byte)135 ;     //  ok

我们一般向下转型的时候,会产生丢失进度的问题。但是当我们使用的整形常量位于 -128~127 不超过 byte 类型范围时,将其赋值给 byte 类型变量是不错产生这样的错误的。

(2)浮点数

浮点数常量的默认类型是 double 型

① double 类型

浮点数常量的默认类型是 double 型,因此可以直接赋值。

double num = 1.23;  // ok

② float 类型

浮点数赋值给 float 类型的变量必须要用 F(f) 修饰,或者强制类型转换

float num = 1.23F;  // ok,1.23F 被F修饰,不能默认是double类型,已经是float类型,可以直接赋值,不发生向下转换
float num = (float)1.23;  // ok

(3)字符类型

Java 的字符型常量值是用单引号引起来的一个字符,如 ‘e’、E’。

注:双引号用来表示字符串,像 “11”、“d” 等都是表示单个字符的字符串。

Java 还允许使用一种特殊形式的字符常量值来表示一些难以用一般字符表示的字符,这种特殊形式的字符是以 ‘\’
开头的字符序列,称为转义字符。

(4)布尔类型

Java 的布尔型常量只有两个值,即 false(假)和 true(真)。

注:在Java中,不能用 0 代表 false(假),非零代表 true(真)

三、数据类型之间的转换

在Java中,整型、实型和字符型被视为简单数据类型,这些类型由低级到高级分别为(byte、short、char)—> int —> long —> folat —> double。简单数据类型之间的转换又可以分为:低级到高级的自动类型转换、高级到低级的强制类型转换、包装类过渡类型转换,通常发生在表达式中或方法的参数传递时

1、自动类型转换(运算、传参)

(1)当一个较低级数据与一个较高级的数据一起运算时,系统将自动将低级数据转换成高级数据,再进行运算。
(2)在方法调用时,低级实参赋值给高级形参时系统将自动将低级数据转换成高级数据,再进行方法的调用。对于多个同名的重载方法,会转换成最"接近"的高级数据并进行调用。

byte b;
int i=b; long l=b; float f=b; double d=b;

(1)如果低级类型为char型,向高级类型(整型)转换时,会转换为对应ASCII码值

char c='c';
int i=c;
System.out.println("output:"+i);  //输出:output:99;

(2)对于 byte、short 和 char 三种类型而言,他们是平级的,因此不能相互自动转换,可以使用强制类型转换

byte i=99 ;
short s=(short)i;
char c=(char)i;

2、强制类型转换

将高级变量转换为低级变量时,需要用到强制类型转换,这种转换可能导致溢出或精度的下降

3、隐含强制类型转换(初始化)

(1)在变量的初始化时,整数的默认类型是 int。byte b = 123; 123 默认是 int 类型,他会隐含强制转换为低级别的 byte 和 short 类型,所以不用显示强制转换;但是 int 类型只能显式强制转换为 long 型,所以 long a = 123L;

(2)浮点型不存在这种情况,因为在定义 float 类型时必须在数字后面跟上 F 或者 f。

4、包装类型与基本类型的转换

(1)使用包装类的构造函数将基本类型的变量手动装箱为相应的包装类

Boolean(boolean value)、 Character(char value)、 Integer(int value)、 Long(long value)、 Float(float value)、 Double(double value)
如:

(2)使用的包装类静态方法 valueOf() 将基本类型的变量手动装箱为相应的包装类

Integer i = Integer.valueOf(1);     // 手动装箱

注意:valueOf() 内部是用的 new 方法来构造对象的

(3)调用包装类中 ××Value() 的实例方法将包装类型手动拆箱为任意类型的简单类型数据

以 Interger 包装类为例,Interger 包装类的所有方法:

利用这种方法,也可以实现不同数值型变量间的转换,例如,对于一个双精度实型类,intValue() 可以得到其对应的整型变量,而 doubleValue() 可以得到其对应的双精度实型变量。

(4)自动装箱和拆箱

在 JDK1.5 引入自动装箱和拆箱的机制后,包装类和基本类型之间的转换就更加轻松便利了。
1)自动装箱:把基本类型转换成包装类,使其具有对象的性质,又可分为手动装箱和自动装箱。

自动装箱实际上自动调用了 valueOf()

2)自动拆箱:和装箱相反,把包装类对象转换成基本类型的值,又可分为手动拆箱和自动拆箱

自动拆箱实际上自动调用了 xxxValue()

public class HelloWorld {public static void main(String[] args) {// 定义double类型变量double a = 91.5;// 手动装箱Double b = new Double(a);// 自动装箱Double c = a;System.out.println("装箱后的结果为:" + b + "和" + c);// 定义一个Double包装类对象,值为8Double d = new Double(87.0);// 手动拆箱double e = d.doubleValue();// 自动拆箱double f = d;System.out.println("拆箱后的结果为:" + e + "和" + f);}
}

5、包装类型、基本类型与字符串的转换

(1)包装类型向字符串的转换

调用包装类的串转换方法:X.toString()

//字符串"32.1"转换double型的值的格式为:String str = "32.1";Double d = new Float("32.1");     String str1 = d.toString();

(2)字符串向包装类型的转换

构造函数parseXxx 静态方法valueOf() 方法

//字符串"32.1"转换double型的值的格式为:String str = "32.1";Double d = new Float("32.1");Double d = Double.parseDouble("32.1");  Double d = Double.valueOf("32.1");

(3)基本类型向字符串的转换

①调用包装类的串转换方法:X.toString();

②自动转换:X+"";

③使用 String 的方法:String.volueOf(X);

(4)字符串向基本类型的转换

① 先转换成相应的包装类实例(构造函数、parseXxx 静态方法或 valueOf() 方法),再进行拆箱(手动、自动)

//字符串"32.1"转换double型的值的格式为:String str = "32.1";double d = new Float("32.1").doubleValue();     // 手动拆箱double d = new Float("32.1");     // 自动拆箱double d = Double.parseDouble("32.1").doubleValue();    // 手动拆箱double d = Double.parseDouble("32.1");    // 自动拆箱double d = Double.valueOf("32.1").doubleValue();    // 手动拆箱double d = Double.valueOf("32.1");    // 自动拆箱

② Character 的 getNumericValue(char ch) 方法

四、基本类型与包装类型的比较

1、equals

equals 方法比较的是真正的值
(1)对于基本类型,由于不是对象,所以不存在地址,更没有equals等方法,故此只有使用“==”来进行值比较
(2) 2个包装类通过 equals 比较,比较的是包装的基本数据类型的值;基本数据类型和包装类通过 equals 比较时,会先把基本数据类型自动装箱包装成对应的包装类型,再进行比较。

double i0 = 0.1;
Double i1 = new Double(0.1);
Double i2 = new Double(0.1);System.out.println(i1.equals(i2));  // true: 2个包装类比较,比较的是包装的基本数据类型的值
System.out.println(i1.equals(i0));  // true: 基本数据类型和包装类型比较时,会先把基本数据类型包装后再比较

阿里巴巴 Java 开发手册:

【强制】所有的相同类型的包装类对象之间值的比较,全部使用 equals 方法比较

说明:对于Integer var = ? 在-128 至 127范围内的赋值,Integer对象是在 IntegerCache.cache 产生,会复用己有对象,这个区间内的 Integer 值可以直接使用 == 进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用己有对象,这是一个大坑,推荐使用 equals 方法进行判断。

2、==

对于基本数据类型,== (双等号)比较的是值
对于包装类型,==(双等号)比较的则是 2 个对象的内存地址
基本数据类型和包装类型通过 == 比较时,会先把包装类自动拆箱再进行值比较(和 equals 是反的)

double i0 = 0.1;
Double i1 = new Double(0.1);
Double i2 = new Double(0.1);
System.out.println(i1 == i2);    // false: new 出来的都是新的对象
System.out.println(Integer.valueOf(i0) ==Integer.valueOf(i0));   // false:valueOf() 内部是用的 new 方法来构造对象的
System.out.println(i1 == i0);    // true: 基本数据类型和包装类比较,会先把包装类拆箱

3、><

(1)在 Java 中,“>” 和 “<” 只能用来判断两个基本数据类型的数值大小关系
(2)对于包装类型,必须先用 xxxValue() 方法将其手动拆箱为基本类型再进行比较。

五、包装类的缓存

Java 对部分经常使用的数据采用缓存技术,在包装类第一次被加载时会创建缓存,当使用等值对象时直接从缓存中获取,从而提高了程序执行性能。(通常只对常用数据进行缓存)。

(1)只有静态方法 valueOf() 方法装箱构造的包装类对象时会用到缓存,valueOf() 方法用到了缓存池

(2)new 方法装箱构造的包装类对象不会使用缓存

valueOf() 方法的源码:

    public static Integer valueOf(int i) {if (i >= IntegerCache.low && i <= IntegerCache.high)return IntegerCache.cache[i + (-IntegerCache.low)];     //如果在缓存范围内,直接获取缓存中的地址return new Integer(i);                                      //否则新建一个对象}

各个包装类型的缓存范围:

(1)valueOf(x) 方法可能会直接从缓存中去取被缓存的同一个对象,所以用 == 比较时可能会为 true。如果 valueOf(x) 中的 x 是缓存范围外的值,那么就会 new 一个新的对象出来,所以用 == 比较的结果一定是 false。
(2)因为 Float 和 Double 没有缓存,所以两个 Float 或 Double 通过 == 比较时,结果永远是 false。

举例:

Integer x = new Integer(123);
Integer y = new Integer(123);
System.out.println(x == y);    // false:new 方法装箱构造的包装类对象不会使用缓存
Integer z = Integer.valueOf(123);
Integer k = Integer.valueOf(123);
System.out.println(z == k);   // true:静态方法 valueOf() 方法装箱构造的包装类对象时会用到缓存
Integer m = Integer.valueOf(189);
Integer n = Integer.valueOf(189);
System.out.println(m == n);   // false: 189 大于缓存池的最大值127 因此每次都会新建一个对象 他们的地址不同
Double p = Double.valueOf(189);
Double q = Double.valueOf(189);
System.out.println(p == q);   // false: Double 没有缓存

六、基本类和包装类在实际使用时的原则

1. 尽量使用 values 方法。最大可能使用缓存,提高程序的效率。

2. 类变量使用包装类。想象有一个和数据库表对应的实体类,如果你使用的基本数据类型,在插入时,可能会插入一些让你意想不到的初始值。

3. 方法的参数要使用包装类使用包装类意味着你在调用时,可以令若干个参数为 null。null 是无意义的。但是如果你使用了基本数据类型,那么,你将不得不传入一个值,即使这个值对你来说,没有什么意义。

4. 方法的返回值要根据是否可为 null 来确定使用包装类还是基本类。当一个方法的返回值,一定不会出现 null 的情况时,推荐使用基本类来作为返回值,这样调用者在拿到这个方法的返回值时,就不必担心它是为 null 了;若返回值可能会出现 null 的情况时,推荐使用包装类来作为返回值

5. 方法内部(局部变量)使用基本类型。基本类型的时间效率和效率上来说,都是要优于包装类的。所以,在方法内部,能使用基本类型尽量不要使用包装类。

6. 小数的计算。严格来说,这条不属于基本类型和包装类的内容,但是,这里顺便提交,当涉及到小数的计算时,要考虑到计算的精度问题,可以使用 BigDecimal,也可以通过缩小计量单位,达到化零为整的目的,这个,根据具体场景来确定。

Java 的数据类型相关推荐

  1. 对Java基本数据类型的再思考

    10年前,我开始学习Java,8种基本数据类型,感觉轻松入门,记忆毫不费力-- 10年后,面试时,突然有人问起java有哪几种基本数据类型?竟然答不出来了,脑子里一点概念都没有了. 为什么会这样? 看 ...

  2. java基本数据类型 以及 double float 二进制表示方法

    Java 基本数据类型分为4类:整型,浮点型,字符型,布尔型. 整数类型: 关键字 占用字节数 byte 1 short 2 int 4 long 8 每个类型的取值范围,我们以int 为例,4个字节 ...

  3. Java基础-数据类型int,short,char,long,float,double,boolean,byte

    Java语言是静态类型的(statical typed),也就是说所有变量和表达式的类型再编译时就已经完全确定.由于是statical typed,导致Java语言也是强类型(Strong typed ...

  4. java i数据类型_数据类型 I

    都来自菜鸟教程,自己总结学习使用, JS 数据类型  没有对比就没有伤害, 字符串(String).数字(Number).布尔(Boolean).数组(Array).对象(Object).空(Null ...

  5. Java 基本数据类型 sizeof 功能

    Java基本数据类型 int     32bit short   16bit long    64bit byte    8bit char    16bit float   32bit double ...

  6. Java 基本数据类型

    Java 基本数据类型 变量就是申请内存来存储值.也就是说,当创建变量的时候,需要在内存中申请空间. 内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据. 因此,通过定义不 ...

  7. 深入理解Java原始数据类型和包装类关于==和equals的比较

    1.运算符 == 对于六大Java数值类原始数据类型,==比较的是数值 对于六大Java原始数据类型对应的包装类,==比较的是内存地址 2.equals() equals()方法只有对象才有,所以我们 ...

  8. java基本语句回文数实验_实验二 java基本数据类型与把持语句.doc

    实验二 java基本数据类型与把持语句.doc 还剩 4页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,喜欢就下载吧,价低环保! 内容要点: 5System.out.println(num ...

  9. 五、吃掉Java基本数据类型,学习Java的基础

    @Author:Runsen @Date:2020/5/20 Java是一个强类型语言,Java中的数据必须明确数据类型.在Java中的数据类型包括基本数据类型和引用数据类型两种. 我是天天看菜鸟和W ...

  10. Java技术分享:Java基本数据类型

    数据类型在计算机语言里面,是对内存位置的一个抽象表达方式,可以理解为针对内存的一种抽象的表达方式.接触每种语言的时候,都会存在数据类型的认识,有复杂的.简单的,各种数据类型都需要在学习初期去了解,Ja ...

最新文章

  1. 【小记】批处理FOR循环中的参数/D
  2. linux渗透测试_渗透测试:选择正确的(Linux)工具栈来修复损坏的IT安全性
  3. uvicorn 更改fastapi 运行host和port
  4. Linux系统编程38:多线程之什么是线程同步以及条件变量函数
  5. 浏览器推送 comet
  6. 深度探秘大数据新应用,2018 中国大数据技术大会(BDTC)强势来袭!
  7. 凸优化第六章逼近与拟合 作业题
  8. Java二分查找法代码
  9. WinAPI双人贪吃蛇
  10. CADD课程学习(2)-- 靶点晶体结构信息
  11. iOS开发 调用系统的震动和提示音
  12. linux7找回删除的文件,centos7 rm -rf 删除文件的找回
  13. 一分钟教会你烫了头发该怎么打理
  14. 史上最拉跨的导线平差程序( by C#)
  15. 老男孩28期学员卞勃森决心书
  16. 老九学堂C++实现小游戏之小公主养成记
  17. java 汉字转拼音_java中将汉字转换成拼音的实现代码
  18. element-plus更换主题色(有手就行)
  19. 内嵌资源html,go 1.16 embed 实现资源文件(html, css, js等)内嵌
  20. CSS空格和换行的处理

热门文章

  1. 明朝那些事_读史有感
  2. 光纤传感器实验模块_光纤传感器实验报告
  3. 计算机中的加减法(二进制补码加减法)
  4. 高通 OpenXR SDK 使用指南(3)
  5. JavaWeb学习心得之JSP内置对象
  6. python寻找质数_寻找质数方法Python2.7版本
  7. java 后端接收JSON数组转换为 String类型存入数据库
  8. 09-把时间当作朋友
  9. SSL证书教程-Letsencrypt
  10. 知识图谱-生物信息学-医学论文(Chip-2022)-BCKG-基于临床指南的中国乳腺癌知识图谱的构建与应用