1. 数据类型
1.1 数据存储
程序 : 可执行文件,一堆命令的集合,属于静态,一般保存在硬盘中
进程 : 进程就是正在执行的程序,是动态的,保存在运行内存中
1 数据存储
想运算,必须先存储
2 数据存储方式
内存 : 可以看做两端无限延伸的线
硬盘 : 螺旋线
3 存储单位
为了保存负数,高位舍弃,作为符号位
1 为负数 0 为 整数
所有类型都需要损失一倍的精度
比如byte 8位 最大值 为 2^7-1 最小值为 -2^7
Byte = -128 ~ 127
Bit = 比特
Byte = 8bit 字节
Short = 2byte = 16bit 短整型
Int = 4byte = 32bit 2147483647 整型
Long = 8 byte = 64bit 长整型
4 存储
正数 存原码
比如保存2 , 2对应的二进制为 0000 0010
负数 存补码
-2 : 1000 0010 原码
1111 1101 反码 除了符号位,1变0,0变1
1111 1110 补码 = 反码+1
1.2 数据分类
本质 就是规定占用内存空间的大小,用位和字节表示
基本数据类型
数值型
整数型 byte,short,int,long
浮点型 float,double
字符型 char
布尔型 boolean
引用数据类型
类,数组,接口
ASCII码 : 字符和整数之间的映射
a = 97
b = 98
c = 99
.....
A = 65
B = 66
C = 67
......
0 = 48
1 = 49
2 = 50
.....
1.3 数据类型的使用
数据类型 名字 = 值;
1.3.1 整数型
byte byte1 = 127;
short s1 = 1235;
int i1 = 2147483647;
// long 声明 如果没有加L , 后面的值默认为int值
// 会发生一次转换,会把int值转换为long类型
long l0 = 2147483647;
// long l0 = 2147483648;
// 如果加L , 则不会转换,值就是long类型
// L不区分大小写 L / l 都可以 , 建议大写,因为小写的l和1不太容易区分
long l1 = 2147483648L;
// 根据名字使用保存的数据
System.out.println(l1);
System.out.println(Integer.MAX_VALUE);
System.out.println(Long.MAX_VALUE);
// 八进制
int i_2 = 012;
System.out.println(i_2);
// 十六进制表示
int i_3 = 0x1f;
System.out.println(i_3);
1.3.2 浮点型
* 浮点型
*
* float : 单浮点 32位
*
* double : 双浮点 64位
*
* 整数 保存的是二进制 , 比如 123456 浮点数 保存的是科学计数法 比如 123+E21
// float 声明 值必须加F , 不区分大小写
float f1 = 1.2F;
// double 声明 值需要加D , 不区分大小写
double d1 = 10.2D;
// java中 整数默认是int,小数默认是double,所以在声明double的时候,D可以 省略
double d2 = 123.321;
// int i = 10;
System.out.println(10.2);
1.3.3 字符型
* 字符型使用
*
* Java中字符型 占用两个字节 也就是16位 并且以英文单引号表示 且只能有一个字符
*
* short 也是16位 : -32768~32767
*
* char 也是16位 : 0-65535 因为char没有负数,所以不需要符号位
public static void main(String[] args) {
short s = 32767;
char c = 35422;
System.out.println(c);
// 引号中 只能有一个字符 空格也算
char c1 = '张';
// 字符可以转换为对应的整数 ASCII
int i1 = c1;
System.out.println(i1);
}
* 转义符 : 把有意义字符转换为无意义字符
* 并且java中char采用unicode编码 \ uxxxx;
// 单引号设置
char c_1 = '\'';
int i_1 = c_1;
// \设置
c_1 = '\\';
i_1 = c_1;
// 制表符
c_1 = '\t';
i_1 = c_1;
// 换行符
c_1 = '\n';
i_1 = c_1;
System.out.println(c_1);
System.out.println(i_1);
// 支持unicode编码
c_1 = '\u4e2d';
i_1=c_1;
System.out.println(c_1);
System.out.println(i_1);
1.3.4 布尔型
* 布尔型使用
public static void main(String[] args) {
// java 中布尔类型不参与任何转换,只有true和false,没有其他的
// 在内存中占用1字节,全0为false,00000001 为true
// 主要应用在流程控制
boolean b1 = false;
b1 = true;
}
1.3.5 类型转换
* java中,八种基本类型,除了布尔型,其他的均可进行转换
*
* 自动类型转换 : 低精度到高精度为自动转换 比如 byte 到 int 就是自动转换
*
* 强制类型转换 : 高精度到低精度为强制转换 比如 int 到 byte
*
* 自动类型转换 byte -> short -> int -> long -> float -> double
* char -> int -> long ->float -> double
byte b1 = 12;
// 自动转换
short s1 = b1;
int i1 = s1;
long l1 = i1;
// int 到 byte 需要强制转换
b1 = (byte) i1;
// 整数保存二进制,而浮点数保存科学计算法,所以float虽然是32位,但是最大值 远大于long
// 所以是自动转换
float f1 = l1;
double d1 = f1;
// char c1 = i1;
char c2 = 'a';
// b1=c2;
// s1=c2;
i1 = c2;
int i_1 = 257;
// 强制转换可能导致数据出错,需谨慎
byte b_1 = (byte) i_1;
System.out.println(b_1);
// --------- 混合运算
// 在进行混合运算时,结果的类型是当前运算中最大的类型
// 比如 int 和 long相加, 结果 是long类型
// 比如 int 和 double相加 结果是 double
int a =1;
byte b = 2;
double c= 3.3;
double result = a+b-c;
// 注意 : 当 byte,short,char,int四种类型中,任意一种或多种进行运算,结果都是int
// 比如 两个byte相加 结果为int
// 比如 byte和char相加 结果为int
short s = 2;
int result1 = b+b;
1.3.6 混合运算
//在进行混合运算时,结果的类型是当前运算中最大的类型
//比如 int 和 long 相加,结果是 long 类型
//比如 int 和 double 相加,结果是 double 类型
int a = 1;
byte b = 2;
double c = 3.3;
double result = a+b-c;
//注意:当 byte,short,char,int 四种类型中,任意一种或多种进行运算,结果都是 int
//比如 两个 byte 相加 结果为 int
//比如 byte 和 char 相加 结果为 int
short s = 2;
int result = b+b;
2. 变量
2.1 常量
常量在程序的整个生命周期中,值不可更改
字面量/直接量
字面量也是有数据类型的
整数默认是整型 int
小数 默认是double
// 字面量
System.out.println(10);
Final修饰称为常量
// 使用final修饰,称为常量,值不能更改
final int i = 20;
// i=1;
System.out.println(i);
2.2 变量
// 变量
int a = 10;
System.out.println(a);
a=11;
System.out.println(a);
System.out.println(a);
可以更改的量,方便进行操作,并且可以复用
2.3 全局变量
全局 : 允许在类外创建变量,和类同级别,所有类都可以直接访问这个变量,不需要二次引用
所谓二次引用,就是指 没有使用 . 操作符 xxx.xxx
而在java中类之外是不允许写变量的,但是可以把一个变量的访问权限设置为public,然后通过类名进行引用调用即可
全局的缺点 就是命名冲突问题
2.4 变量声明
* 变量声明 :
*
* 数据类型 变量名 = 值;
int i_1 = 10;
char c_1 = '张';
boolean b_1 = false;
// 字符串,用双引号表示,String是引用类型
String str = "我叫xxxxx";
2.5 变量作用域
* 作用域 一个大括号 就是一个作用域
// 变量不能先使用 后声明
// System.out.println(i_1);
int i_1 = 10;
char c_1 = '张';
boolean b_1 = false;
// 字符串,用双引号表示,String是引用类型
String str = "我叫xxxxx";
// 通过名字 找到对应的变量
System.out.println(i_1);
{
System.out.println(i_1);
int a = 1;
System.out.println(a);
}
// 访问不到,因为一个变量的使用作用域,不会超过包含它的这个大括号
// System.out.println(a);
}
2.6 变量分类
* 局部变量 : 在方法中声明的变量称为局部变量,该变量只能在该方法中被使用
* 并且直接通过名字调用该变量即可 且 局部变量没有默认值,必须赋值
*
* 静态变量 : 在类体中 使用 static声明的变量,和方法是平级关系
* 并且 需要通过类名.静态变量名 才能调用 另外在当前类中调用当前类的静态变量时,类名可以省略
* 默认值 : 整数 默认是 0 , 小数 默认 0.0 , 布尔型 默认 false , 字符型 默认 \u0000 , 引用类型 默认 null
*
* 成员变量 : 在类体中 没有使用 static声明的变量,和方法是平级关系
* 并且 成员变量 需要通过 对象引用.成员变量 才能调用
* 默认值 : 整数 默认是 0 , 小数 默认 0.0 , 布尔型 默认 false , 字符型 默认 \u0000 , 引用类型 默认 null
// 静态变量
static int age = 18;
static String name;
// 成员变量
double score;
public static void main(String[] args) {
int i = 2;
System.out.println(i);
int a ;
// 局部变量没有默认值,不赋值不能使用
// System.out.println(a);
// 调用静态变量
System.out.println(Var_03.age);
// 调用当前类中的静态变量时,类名可以省略
System.out.println(age);
System.out.println(name);
}
3. 运算符
3.1 算数运算符
int a = 10;
int b = 3;
// 3
System.out.println(a / b);
// 1
System.out.println(a % b);
// 注意小数相加
double a1 = 0.1;
double a2 = 0.2;
// 0.30000000000000004
// 一定要注释,千万不要判断小数是否相等
System.out.println(a1 + a2);
++
// 注意 : 优先级 单目 > 双目 > 三目 (三元)
// ++ : 把值拿出来 +1 再放回去 (会发生赋值)
// i++ : 先赋值 再自身+1(先确定I的值)
// ++i : 先自身+1 再赋值
int s = 100;
// s = s + s++;
s = s + ++s;
System.out.println(s);
// 如果 k++和 ++k单独出现 没有任何区别,自身+1 完事
k = 100;
// k++ : 需要占用两块空间 ,一个是k空间,一个是临时空间用来保存+1之前的数据
// ++k : 需要占用1块空间,只需要保存+1之后的数据即可
// 但是 基本可以忽略,因为编译器也会帮我们进行优化
// 在编译器优化之后,++i和i++在这里没有区别。而i++看起来更美观,所以会把单独出现的++i转换为i++
++k;
System.out.println(k);
// 源码
int i = 2;
i++;
++i;
i = ++i + 2;
i = i++ + 2;
// 编译之后 class文件中 是这样
// int i = 2;
// i++;
// 因为是单独出现的,所以把++i也转换成了 i++
// i++;
// 因为是混合运算,所以 ++i 就是 ++i , i++就是 i++ 不会进行转换
// i = ++i + 2;
// i = i++ +2;
3.2 关系运算符
* 关系运算符
*
* > >= < <=
*
* == : 判断相等,基本类型比较值,引用类型比较地址 != : 判断不相等
*
* 关系运算的结果 是布尔型 true/false
public static void main(String[] args) {
int a = 10;
int b = 11;
boolean result = a < b;
// true
System.out.println(result);
// true
System.out.println(a<=b);
// false
System.out.println(a>b);
// false
System.out.println(a>=b);
// false
System.out.println(a==b);
// true
System.out.println(a!=b);
}
3.3 位运算符
* & 位与 , 两边都是真 结果才是真,如果两把是数值,则是与运算
* | 位或 , 两边一个为真,结果就是真
* ! 位非 , 取反,真就是假,假就是真
* ^ 位异或 ,两边不一样 结果就是true
* ~ 按位非 , 0 二进制 0000 0000 按位非(按位取反) 1111 1111
* 1111 1111 补码 1111 1110 反码 1000 0001 源码
// false
System.out.println( 1<2 & 2>3);
// true
System.out.println( 1<2 | 2>3);
// false
System.out.println(!true);
// true
System.out.println(false ^ true);
// 按位非 -1
System.out.println(~10);
// 如果两边是数字,则会进行与运算
// 先把两个数转换为对应的二进制,然后每位进行比较,都是1则取1,反之取0
// 0000 1001
// 0000 1110
// 0000 1000 = 8
System.out.println(9 & 14);
* >> : 右移运算符(考虑符号位,再怎么移动,符号位不变)
* 向右移动一次 就等于 除以2
* 8 >> 2 : 000000 10
* 如果是正数 左边补0(符号位之后补0) , 如果是负数 左边 补1
* << : 左移运算符(考虑符号位,再怎么移动,符号位不变)
* 向左移动一次,.就等于 乘以 2
* 2<<2 向左移动两次,向右补0(正负数 都补0)
* >>> : 右移运算符(不考虑符号位,符号位之前补0,并且不管正负数 只补0)
* 8 >> 2 和 8 >>> 2 没有区别
* -8 >> 2 和 -8 >>> 2 就有区别了
// 如果两边是数字,则会进行与运算
// 先把两个数转换为对应的二进制,然后每位进行比较,都是1则取1,反之取0
// 0000 1001
// 0000 1110
// 0000 1000 = 8
System.out.println(9 & 14);
System.out.println(-8 >> 2);
System.out.println(2 << 2);
// 1000 0010
// 1000 1000
// 10 000101
System.out.println(-2 << 2);
System.out.println(-8 >>> 2);
System.out.println(-1>>>1);
* && : 短路与,且 两边都是真 结果才是真,
* || : 短路或 , 或 两边一个为真,结果就是真
// 测试短路和非短路
// boolean result = (a1 == b1 | a1 > b1++);
boolean result = (a1 == b1 || a1 > b1++);
System.out.println(result);
System.out.println(b1);