-
java是一门强类型语言,定义一个变量时必须要声明明确该变量的类型
int age = 10;// age这个变量只能保存整型数值,无法保存小数和字符串等其他
Python和JS都是弱类型语言
java的数据类型
所有的数据类型都有默认值
类中的属性才具备默认值,方法中的局部变量不存在默认值
-
八大基本数据类型
-
【数值型】 ❗都是有符号的
整型:byte【1】<short【2】<int【4】<long【8】 默认值0
浮点型:float【4】<double【8】 默认值0.0
-
【字符型】
char【2】 默认值‘\u0000’
-
【布尔型】
boolean【JVM没有明确规范 基本上是1bit位】 默认值false
-
-
数组、类、接口
引用数据类型
数值型数据类型的最高位不存储具体数据,最高位0表示正数,1表示负数
这里涉及原码、反码、补码的知识点
int是4字节,32个比特位,由于最高位不存储数字,max值是2^31-1,min值是-2^31
byte的数据范围是-128~127
外存和内存的区别?
程序中的所有数据,在运行起来后,保存在计算机的内存中
CPU直接和内存打交道,CPU所有运行的数据都存储在内存中
内存的读写速度要比硬盘(外存)快得多的多,快10^3~10^5不等
内存的造价较高,读写速度快,容量低,一旦断电内存中的数据都会清空
外存造价低,读写速度慢,容量较大,断电数据仍然保留
当启动电源时,操作系统的内核就会从外存加载到内存,加载完毕后,操作系统运行在内存中,CPU正常工作,从内存中读写数据
计算机存储数据的基本单位
bit:二进制位 10变成二进制是1010(使用4个比特位存储)
byte:字节 计算机保存的数据以字节为基本单位
1byte = 8bit
1KB = 1024 byte
1MB = 1024 KB
1GB = 1024 MB
1TB = 1024 GB
变量和常量
变量:定义后数值可以改变的内容称为变量,能变的只有数值内容,数据类型无法改变
常量:定义之后,数值无法改变,称之为常量
【基本语法】数据类型 变量名称 = 初始值;
int a = 10; //定义了一个整型变量,变量名称(标识符)为a,初始值为10
在一行之中可以定义多个相同数据类型的变量:
int a = 10, b = 20, c; //a初始值为10,b为20,c为0
❗在java任意的方法内部声明的变量都属于局部变量,局部变量没有默认值,当方法调用结束,方法中的所有局部变量都会被销毁,内存释放,局部变量必须在使用前赋值,不然会报错
int b;
System.out.println(b); //会报错:可能尚未初始化变量b
❗在类中定义的变量才存在默认值
public class IntTest{
//在类中定义的变量存在默认值,叫做成员变量
//默认值就是该数据类型对应的默认值
int a; //默认值为0
public static void main(String[] args){
int b; //方法中定义的变量叫做局部变量
b = 10;
System.out.println(b);
}
}
变量的数据范围
任何数据类型都有其保存的范围,超出这个范围就会产生数据溢出问题
System.out.println(Integer,MAX_VALUE); //输出2147483647
System.out.println(Integer,MIN_VALUE); //输出-2147483648
Integer是整型的包装类
包装类:在java中一切皆对象,认为一切事物都可以使用类来进行描述,8大基本类型不属于类
因此在java中,将8大基本类型都有对应的类进行包装,这种类称为包装类
8大基本类型对应的包装类(引用类型) 数值型:Byte Short Integer Long 浮点型:Float Double 字符型:Character 布尔型:Boolean
String是java中的字符串类型,是引用类型,是字符串的类
关于长整型Long
int a = 10;
int b = 10L; //为了区分10到底是长整型还是整型,定义长整型时,一般后加L或l表示为长整型
来看下面这个问题:
int a = Interger.MAX_VALUE;
long b = a + 1;
System.out.println(b); //long比int数据范围大,但是依旧出现了数据溢出
赋值过程,先计算a+1的值,然后将计算后的值赋值给b 但是a+1已经超出了int的数据范围,溢出,变成了整型的最小值,将溢出后得到的最小值赋值给了b
正确的代码:
long a = Interger.MAX_VALUE;
long b = a + 1;
System.out.println(b);
假设一个数比长整型的最大值还要大,怎么办?基本数据类型已经不够用了!
当大数据时,采用BigInterger类来存储,也可以使用字符串String类型来存储大整数
System.out.println(10+1l); //输出结果为11 *滴滴的笔试题
byte<short<int<long 一般场景下用int就足够,int放不下了用long 当进行网络编程或IO编程时,基本操作单位是byte 字节是计算机存储表示的基本单位
关于float和double
浮点型变量 float【4字节】<double【8字节】 双精度浮点数double:双精度可以保证小数点后12位之内的数字一定是准确的 单精度浮点数float:保证小数点后6位以内的有效数字【一般很少用】
int a = 10;
int b = 20;
System.out.println(a/b); //输出为0
整型/整型 输出浮点型
若是要输出正确答案0.5,则需要改成:
double a = 10;
double b = 20;
System.out.println(a/b); //输出为0.5
计算机中存储的都是二进制010101010,小数在计算机中存储时使用整数来模拟小数,所以有时会有精度丢失的问题(工程中精确到12位已经基本够用了)
double num = 1.1;
System.out.println(num * num); //输出1.210000000000002
若在某些精度要求特别高的场合,使用BigDecimal来存储小数
用f或F来表示此时定义的数为单精度浮点型
float a = 10.0F;
字符型char
对应的包装类为Character
char a = 'a';
char b = '哈';
char d = 'あ';
计算机只认识0和1的二进制数,那么语言文字是如何存储在计算机中的?
通过编码映射
如何将不同的文字符号转为数字,这个转换规则称之为编码规则
一般英文字母采用ASCll编码
c语言字符使用ASCll编码来存储字符(7位二进制),对中文和其他语言不友好 java语言采用unicode编码,采用16位编码(2字节),支持地球上所有语言
布尔型Boolean
Boolean类型 只有两个数值,不是true就是false
boolean a = falsa;
boolean b = true;
表示真就是true,表示假就是false【和c语言不同,没有0和1之说!!!】 不能将布尔值boolean和整型的0和1进行转换,两者毫无关系!!!
字面量
字面量:直接写出来的数值称之为字面量,字面量也存在数据类型 10:整型字面量,默认为int类型 10.1:浮点型字面量,默认为double类型 ‘a’:字符字面量,char类型 false:布尔值字面量,boolean类型 “abc”:字符串字面量,String类型
类型转换与类型提升
小类型转换为大类型是自动转换
大类型转换为小类型需要强制类型转换,且有精度丢失的问题
int a = 100;
long b = 10L;
b = a; //int赋值给了long,自动将a提升为long类型然后赋值给b
a = (int)b; //long赋值给int,大转小,需要强制类型转换
❓提问,以下是否正确:
float b = 10.1;
编译出错,10.1是字面量,double类型,double转float是大转小,需要强制类型转换
改正:
float b = 10.1F; //改法1
float b = (float)10.1; //改法2
关于int,byte,char之间的转换问题
计算机存储数据时默认采用4字节存储,所以小于4字节的数据类型(byte、short、char),隐式提升为int之后进行存储(boolean除外)
byte a = 10; //为什么没报错?
按照规则需要强制类型转换,此时没报错的原因是因为a这个变量在存储时会隐式提升为int进行存储
byte b = 130; //报错了!为什么?
超过127,超出了数据范围,超过了byte的保存范围,必须进行强转,有精度丢失问题
改正后:
byte b = (byte)130;
看以下:
byte a = 10;
byte b = 20;
byte c = a + b; //会报错
byte f = 1 + 2; //不会报错
cpu读写内存都是以4字节进行读取,a和b存储在内存中会自动提升为int类型 a和b已经成为int类型,相加的结果也是int类型
两个变量相加,先对类型进行提升,然后运算,再将运算结果赋值
两个常量相加,先计算常量数值,然后判断是否满足类型范围,再赋值
JVM无法判断a+b的值是否在byte的取值范围内,故报错
解释一:因为a与b都是变量,变量相加的结果在编译期间无法得知,不知道是否会超过byte的取值范围,所以编译器会报错
解释二:a+b结果是int类型,int类型的值不能赋值给byte类型
正确:
byte c = (byte)(a+b);
同样的规则也适用于char和int的相互转换
char是2字节 int是4字节 int>char
char c = 'a'; //char类型赋值给int,自动提升
int b = c; //按照编码规则,将字符转换为对应的整数97
char d = b; //这个不行,int转char属于大到小,需要强转
类型提升
不同数据类型进行运算时,自动会将小类型提升为大类型然后参与运算
int a = Integer.MAX_VALUE;
long b = a + 1L;
System.out.println(b); //编译正确
a的数据类型为int,和1L相加时,数据类型提升为long
int + long -> long + long = long
int a = 1;
double b = 2;//此处有2个类型提升
//2是整型字面量,int赋值给double是自动提升,转成double类型2.0
//int / double -> double / double = double
System.out.println(a/b); //输出0.5
❗能相互转换的数据类型之间才能强转或自动提升,boolean和其他任何类型毫无关系,无法强转也无法提升
-
隐式类型转换
byte→short(char)→int→long→float→double
(这里指的是只有前面的数据类型能随便转换成后面的)
实际开发中这样的类型转换很多,但没有为这种转换提供专门的语法,都是由虚拟机自动完成