1.Java数据类型划分
8大基本数据类型:
数值型:
整型:byte(1字节)
浮点型:float(4字节)
字符型:
char:2字节,默认值为'\u0000'
布尔型:
真为true,假为false,默认值为false
在Java中,0和1不能代表真假
引用数据类型:
数组,类,接口都属于引用数据类型
class关键字声明的全是类
注:所有的数据类型的默认值必须在类中定义变量才可以,局部变量不存在默认值,必须赋值后再使用
在任意方法中不能定义静态变量static,静态变量必须定义在类中
2.常量和变量
常量:一旦定义后无法修改的值称为常量
字面常量:直接写出来的值都称为字面常量
eg:10;//int类型字面量
普通常量:
在Java中定义一个普通常量使用final关键字
final修饰的变量就成为了常量,一旦赋值后无法修改
//int字面量 10为整型字面量 无法修改
int a=10;
//double字面量 10.1为浮点数字面量,无法修改
double b=10.1;
//a和b是变量,可以修改
a=20;
b=20.2;
System.out.println(a);
System.out.println(b);
//c被final修饰,是常量 无法修改
final int c=3;
System.out.println(c);
常量的命名规范:单词使用纯大写字母表示,多个单词之间使用_分隔
Java中的数值型不存在无符号数,所有数值类型默认带符号
变量的具体定义
语法:数据类型 标识符的名称=初始值;
//变量定义,a就是整型变量
int a=10;
//b就是浮点数变量
double b=10.1;
//c就是字符型变量
char c='a';
//声明和赋值分开
int a;
int A;
double b;
当数据类型的变量保存不下某个数值时,就会发生溢出问题
int a;
int A;
a=Integer.MIN_VALUE;
A=Integer.MAX_VALUE;
System.out.println(a-1);
System.out.println(A+1);
此时A存储的是整型的最大值,当A+1超出了整形的保存范围,编译器进位后只保存前32位,看到的效果就变成了整型的最小值
当字面量数值超出了整型的范围时,编译报错
关于整型字面量的进制问题
0b开头表示2进制整型字面量
0开头表示8进制整型字面量
0x开头表示16进制整型字面量
int a=10;
int b=010;
int c=0b10;
int d=0x10;
长整型变量
声明长整型变量
要表示一个长整型变量需要在整数部分后面加上l或者L(推荐L)
//声明一个长整型变量
long a=10;
//直接写出来的整型字面量都是int型
//声明一个长整型变量,在整数后面加l或L
long b=40000000000L;
byte类型
1字节,[-128,127]
一般byte是网络传输和文件IO流的基本单位,因此当进行网络编程,IO流使用的都是byte类型
总结:一般场景下使用int,int放不下用long,byte常用于网络编程和文件IO流的操作
浮点型变量
1.双精度浮点型 double 8字节
浮点型字面量默认是double类型的
double a=10.1;
int b=1;
int c=2;
System.out.println(b/c);//会忽略小数部分
//更换数据类型
double d=1.0;
double e=2.0;
System.out.println(d/e);
关于小数的精度问题
double x=1.1;
double y=1.1;
System.out.println(x*y);//可能出现一些错误数据
解决办法
//解决办法1:double类型只看小数点后12位,float类型只看小数点后6位
//解决办法2:使用JDK提供的BigDecimal类
BigDecimal b1= BigDecimal.valueOf(1.1);
BigDecimal b2=BigDecimal.valueOf(1.1);
System.out.println(b1.add(b2));
System.out.println(b2.subtract(b1));
System.out.println(b1.multiply(b2));
System.out.println(b1.divide(b2));
2.float
单精度浮点数,4字节,只看小数点后6位是准确值
声明float类型的字面量,在小数后面加f或者F
字符型
char 2字节 (无论什么语言的字符,无论什么操作系统,统统两字节保存,使用Unicode编码)
char c1='a';
char c2='A';
char c3='李';
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
布尔类型变量
表示真假,一般搭配分支语句(if)使用
表示真就是true,表示假就是false,不存在01的转换
类型转换
1.隐式提升(小类型->大类型)
1.1赋值
//赋值
int a=10;
long b=100;
long c=a;
1.2进行数学运算
小类型和大类型共同参与运算,首先要将小类型提升为大类型之后再进行运算
//转换前
int d=1;
int e=2;
double f=d/e;
System.out.println(f);
//转换后
int g=1;
double h=2;
double i=g/h;
System.out.println(i);
大类型没有参与运算,只是最终存储值而已,参与运算的数值类型不会提升
2.显示提升(大类型->小类型)
两个数据类型有关系才能转换,转换可能报错
强制类型转换可能会导致丢失精度
//丢失精度
double c=1.5;
int d=1;
d=(int)c;
System.out.println(d);
//数据溢出
long e=Integer.MAX_VALUE+1L;
int f;
f=(int)e;
System.out.println(f);
毫无关系的类型之间不能发生类型转换
boolean x=true;
int y=1;
//转换会报错
//y=(int)x;
int与byte的互相转换
注:CPU在内存中进行数据读写时,默认都是按照4字节来读写数据的,为了硬件上实现方便,byte,short,char这种低于4字节的类型,最终读写参与运算时会提升为int类型再进行计算
byte->int自动提升
byte i=10;
byte j=2;
int k=i+j;
System.out.println(k);
将整型字面量赋值给byte类型时,若整型字面量的数值在byte范围之内,可以直接赋值,超出byte保存范围需要强制类型转换
byte a=125;
byte b=(byte)128;
当把一个int变量赋值给byte时,无论这个变量的值在不在byte的保存范围之内,都需要强转
int c=10;
byte d=(byte)c;
被final修饰的变量,除了值定义后不可更改,存储在计算机内部时,类型也不能转换
final byte x=10;
final byte y=20;
byte z=x+y;
char和int的相互转换问题
char->int 按照编码规则自动转换
char a='a';
char b='A';
char c='李';
int num1=a;
int num2=b;
int num3=c;
int->char
int 数值必须在char的范围内(2^15)的数字才能有对应的字符对应
//字母大小写互相变换
char i='a';
char j=(char)(i-32);
System.out.println(j);
String和int的相互转换
int->String
直接“+”
Java中任意类型只要和字符对象+,统统都转为字符串类型而后进行字符串的拼接操作
//优化前
String c="计算结果"+a+b;
System.out.println(c);
//优化后
String str1="计算结果"+(a+b);
System.out.println(str1);
任意类型->String
使用String提供的valueOf方法
//任意类型转换为字符串
String str2=String.valueOf(10);
String str3=String.valueOf(10.1);
String str4=String.valueOf(true);
System.out.println(str2);
System.out.println(str3);
System.out.println(str4);
String->int
调用Integer.parselnt(str)
前提是这个str字符串变量必须是由纯数字组成的,不能包含其他数据
//将字符串转为int
String str5="12345";
int i=Integer.parseInt(str5);
System.out.println(i+1);
System.out.println(str5+1);
float和long的互相转换
float转换为二进制,大概是2^128数量级的数字
float->long属于小类型到大类型的隐式提升
long a=10;
float b=a;
System.out.println(b);
运算符
算术运算符:+ - * / %
int a=10;
int b=20;
System.out.println(a+b);
System.out.println(a-b);
System.out.println(a*b);
System.out.println(a/b);
System.out.println(b%a);
增量运算符
+=,-=,/=,*=,%=,++,--
a+=1;//a=a+1 3
System.out.println(a);
a-=2;//a=a-2 1
System.out.println(a);
a*=3;//a=a*3 3
System.out.println(a);
a/=1;//a=a/1 3
System.out.println(a);
a%=2; //a=a%2 1
System.out.println(a);
后置++,先取值后++
前置++,先运算再取值
System.out.println(a++);//1
System.out.println(++a);//3
关系运算符
计算结果为布尔值,要么是true,要么是false
==,<,>,!=,<=,>=
int a=10,b=20;
System.out.println(a==b);
System.out.println(a!=b);
System.out.println(ab);
当需要多次进行关系运算符的计算,不能连着写,需要搭配逻辑运算符一起计算
逻辑运算符
参与运算的表达式都必须是布尔表达式,表达的结果都必须是布尔值,不能是其他类型
&&逻辑与
||逻辑或
!取反
&&:表达式1&&表达式2
只有当表达式1和表达式2都返回true时,最终结果才为true
只要有一个表达式返回false,整个计算结束,直接返回false,剩下的条件就不再判断了(短路操作)
int a=10,b=20;
System.out.println(a==10&&b==20);
System.out.println(a<5&&b>10);
System.out.println(a>5&&a<15);
System.out.println(a<5&&a/0==0);
||:表达式1||表达式2
当表达式都为false时,才返回false,只要有一个true,直接返回true(短路操作)
System.out.println(a==10||b<5);
System.out.println(a>20||b<5);
System.out.println(a<14||b/0==0);
逻辑取反!操作的是布尔表达式,真变为假,假变为真
System.out.println(!(a==10));
位运算符
&两个二进制位都为1,返回1
|两个二进制位都为0,返回0
^两个二进制位不相同返回1,否则返回0(在工程中做查找出现1次的数字)
~取绝对值,加符号,-1
int a=10,b=20;
System.out.println(a&b);
System.out.println(a|b);
System.out.println(a^b);
System.out.println(~a);
移位运算
>>:右移
<<:左移
>>>:无符号右移
//取两个数的平均值
int i=a+(b-a)>>1;
System.out.println(i);
三目运算符
返回值=布尔表达式1?表达式2:表达式3
当布尔表达式值为true时,取值2,否则取3
int max=a>b?a:b;
System.out.println(max);
double c=true?1:2.0;
System.out.println(c);
运算符的优先级:不需要记忆,需要优先计算的加括号