前言:
关于Java的文章我以后会通过阶段性的文章来对自己学到的知识进行总结性的文章,所以文章的篇幅可能会显得比较长,但是我会尽力让文章写的逻辑清晰。
一:变量和运算符:
1.1 关键字、保留字
关键字:被Java赋予特殊含义的字符串。
①官方规范种有五十个关键字。
②true, false, null 虽然不是关键字,但是可以当作关键字来看待。
保留字:goto, const
1.2标识符
①标识符:凡是自己可以命名的地方都叫标识符。
比如:类名, 变量名, 方法名, 接口名, 包名, 常量名等
②记住:标识符的命名规则(必须要遵守以下几点,不然编译不通过)
>由26个英文字母大小写, 0-9, _ 或 $ 组成
>数字不可以作为开头
>不可以使用关键字和保留字, 但能够包含关键字和保留字(不完全相同就行)
>Java中严格区分大小写, 长度的话没有限制,别太离谱就行
>标识符不能包含空格,单词和单词之间用大写字母隔开,比如学生名字: studentName
③记住: 标识符的命名规范(建议遵守.如果不遵守, 编译和运行都会很正常,对于程序无影响,就是不便于理解)
>包名:多单词组成是所有字母都小写:xxxyyyzzz
例如: java.lang, com.atguigu.bean
>类名, 接口名:多单词组成时, 所有的单词的首字母大写: XxxYyyZzz
例如: HelloWorld, String, System
>变量名, 方法名: 多单词组成时, 第一个单词首字母小写, 第二个单词开始每个单词首字母大写:xxxYyyZzz
例如: age, name, bookName, main, binarySearch, getName
>常量名:所有字母都大写,单词和单词之间用下划线连接:XXX_YYY_ZZZ
例如: MAX_VALUE, PI, DEFAULT_CAPACITY
前面所说的: 最主要要起到一个见名知意的作用!!!!!
1.3变量的基本使用(重点)
1.变量的理解:
内存中一个存储的区域, 该区域的数据可以在同一个类型范围内不断变化
2.变量的构成包含三个要素:
数据类型, 变量名, 存储的值
3.Java中变量声明的格式:
数据类型 变量名 = 变量值
class VariableTest {
public static void main(String[] args) {
//定义变量的方式1:
char gender; //过程1:变量的声明
gender = '男'; //过程2:变量的赋值(或初始化)gender = '女';
//定义变量的方式2:声明与初始化合并
int age = 10;
System.out.println(age);
System.out.println("age = " + age);
System.out.println("gender = " + gender);//在同一个作用域内,不能声明两个同名的变量
//char gender = '女';gender = '男';
//由于number前没有声明类型,即当前number变量没有提前定义。所以编译不通过。
//number = 10;byte b1 = 127;
//b1超出了byte的范围,编译不通过。
//b1 = 128;}
public static void main123(String[] args) {
//System.out.println("gender = " + gender);char gender = '女';
}
}
①变量名都有它的作用域, 变量只在作用域内是有效的, 出了作用域就失效了
②在同一个作用域内, 不能声明两个同名的变量
③定义好变量后, 就可以通过变量名的方式对变量进行调用和运算
④变量值在赋值时, 必须满足变量的数据类型, 并且在数据类型有效的范围内变化
1.4基本数据类型变量的使用(重点)
1.Java中的变量按照数据类型来分类:
基本数据类型(八种):
整形: byte \ short \ int \ long
浮点型: float \ double
字符型: char
布尔型; boolean
引用数据类型:
类(class)
数组(array)
接口(interface)
枚举(enum)
注解(annotation)
记录(record)
/*
测试整型和浮点型变量的使用
*/
class VariableTest1 {
public static void main(String[] args) {
//1.测试整型变量的使用
// byte(1字节=8bit) \ short(2字节) \ int(4字节) \ long(8字节)byte b1 = 12;
byte b2 = 127;
//编译不通过。因为超出了byte的存储范围
//byte b3 = 128;short s1 = 1234;
int i1 = 123234123;
//① 声明long类型变量时,需要提供后缀。后缀为'l'或'L'
long l1 = 123123123L;//② 开发中,大家定义整型变量时,没有特殊情况的话,通常都声明为int类型。
//2.测试浮点类型变量的使用
//float \ double
double d1 = 12.3;
//① 声明long类型变量时,需要提供后缀。后缀为'f'或'F'
float f1 = 12.3f;
System.out.println("f1 = " + f1);//② 开发中,大家定义浮点型变量时,没有特殊情况的话,通常都声明为double类型,因为精度更高。
//③ float类型表数范围要大于long类型的表数范围。但是精度不高。
//测试浮点型变量的精度
//结论:通过测试发现浮点型变量的精度不高。如果在开发中,需要极高的精度,需要使用BigDecimal类替换浮点型变量。
//测试1
System.out.println(0.1 + 0.2);//测试2:
float ff1 = 123123123f;
float ff2 = ff1 + 1;
System.out.println(ff1);
System.out.println(ff2);
System.out.println(ff1 == ff2);
}
}
/*
测试字符类型和布尔类型的使用
*/
class VariableTest2 {
public static void main(String[] args) {
//1.字符类型:char(2字节)//表示形式1:使用一对''表示,内部有且仅有一个字符
char c1 = 'a';
char c2 = '中';
char c3 = '1';
char c4 = '%';
char c5 = 'γ';
//编译不通过
//char c6 = '';
//char c7 = 'ab';//表示形式2:直接使用Unicode值来表示字符型常量。
char c8 = '\u0036';
System.out.println(c8);//表示形式3:使用转义字符
char c9 = '\n';
char c10 = '\t';
System.out.println("hello" + c10 + "world");//表示形式4:使用具体字符对应的数值(比如ASCII码)
char c11 = 97;
System.out.println(c11);//achar c12 = '1';
char c13 = 1;//2. 布尔类型:boolean
//① 只有两个取值:true 、 false
boolean bo1 = true;
boolean bo2 = false;
//编译不通过
//boolean bo3 = 0;
//② 常使用在流程控制语句中。比如:条件判断、循环结构等
boolean isMarried = true;
if(isMarried){
System.out.println("很遗憾,不能参加单身派对了");
}else{
System.out.println("可以多谈几个女朋友或男朋友");
}
//③ 了解:我们不谈boolean类型占用的空间大小。但是,真正在内存中分配的话,使用的是4个字节。
1.5基本数据类型变量间的运算规则(重点)
1.5.1自动类型提升:
基本数据类型变量间的运算规则.
1.这里提到的可以做运算的基本类型有七种(不包括boolean)
2.运算规则包括:
①自动类型提升
②强制类型转换
3.规则:当容量小的变量与容量大的变量做运算时,结果自动转换为容量大的数据类型。
byte 、short 、char ---> int ---> long ---> float ---> double
特别的:byte、short、char类型的变量之间做运算,结果为int类型。
说明:此时的容量小或大,并非指占用的内存空间的大小,而是指表示数据的范围的大小。
long(8字节) 、 float(4字节)
(其实总结来说就是先浮点型, 因为更精确一点,精度从高到低排,然后整形,精度从高到低排)
class VariableTest3 {
public static void main(String[] args) {
int i1 = 10;
int i2 = i1;long l1 = i1;
float f1 = l1;
byte b1 = 12;
int i3 = b1 + i1;//编译不通过
//byte b2 = b1 + i1;
//**********************************************
//特殊的情况1:byte、short之间做运算
byte b3 = 12;
short s1 = 10;
//编译不通过
//short s2 = b3 + s1;
i3 = b3 + s1;byte b4 = 10;
//编译不通过
//byte b5 = b3 + b4;//特殊的情况2:char
char c1 = 'a';
//编译不通过
//char c2 = c1 + b3;
int i4 = c1 + b3;
//**********************************************
//练习1:
long l2 = 123L;
long l3 = 123; //理解为:自动类型提升 (int--->long)//long l4 = 123123123123; //123123123123理解为int类型,因为超出了int范围,所以报错。
long l5 = 123123123123L;//此时的123123123123L就是使用8个字节存储的long类型的值
//练习2:
float f2 = 12.3F;
//编译不通过
//float f3 = 12.3; //不满足自动类型提升的规则(double --> float)。所以报错//练习3:
//规定1:整型常量,规定是int类型。
byte b5 = 10;
//byte b6 = b5 + 1;
int ii1 = b5 + 1;
//规定2:浮点型常量,规定是double类型。
double dd1 = b5 + 12.3;//练习4:说明为什么不允许变量名是数字开头的。为了“自洽”
/*
int 123L = 12;
long l6 = 123L;
*/
}
}
1.5.2强制类型转换
规则:
1.如果需要将容量大的变量的类型转换为容量小的变量的类型, 需要使用强制类型转换
2.强制类型转换需要使用强制符:( ) . 在( )内要指明转换为的数据类型
3.强制类型转换的过程中可能会导致精度损失
比如说浮点型转换为整形 , 就会损失小数部分.
class VariableTest4 {
public static void main(String[] args) {
double d1 = 12;//自动类型提升
//编译失败
//int i1 = d1;int i2 = (int)d1;
System.out.println(i2);
long l1 = 123;
//编译失败
//short s1 = l1;
short s2 = (short)l1;
System.out.println(s2);
//练习
int i3 = 12;
float f1 = i3;//自动类型提升
System.out.println(f1); //12.0float f2 = (float)i3; //编译可以通过。只不过可以省略()而已。
//精度损失的例子1:
double d2 = 12.9;
int i4 = (int)d2;
System.out.println(i4);//精度损失的例子2:
int i5 = 128;
byte b1 = (byte)i5;
System.out.println(b1); //-128
//实际开发举例:
byte b2 = 12;
method(b2);long l2 = 12L;
//编译不通过
//method(l2);
method((int)l2);
}public static void method(int num){ //int num = b2;自动类型提升
System.out.println("num = " + num);
}
}
1.6 String类的使用 , 与基本数据类型变量间的运算(重点)
String的认识 : 字符串 , 使用一对双引号表示 , 内部包含0个 , 1个 , 或多个字符.
String和8种基本数据类型变量间的运算 : + , 运算的结果是String类型
基本数据类型和String的运算
一 , 关于String的理解
1.String类 , 属于引用数据类型 , 俗称字符串
2.String类型的变量 , 可以使用一对双引号的方式进行赋值
3.String声明的字符串内部 , 可以包含0个 , 1个 , 或多个字符
二 , String与基本数据类型之间的运算
1 . 这里的基本数据类型包括boolean在内的8种
2 . String与基本数据类型变量间只能做连接计算 , 使用 + 表示
3 . 运算的结果是String类型.
4 . 也可以使用相应的方法将字符串转变为对应的数据类型,用到了包装类
下面的例子中会写 : parseInt
class StringTest {
public static void main(String[] args) {
String str1 = "Hello World!";
System.out.println("str1");
System.out.println(str1);
String str2 = "";
String str3 = "a";//char c1 = 'a';
//测试连接运算
int num1 = 10;
boolean b1 = true;
String str4 = "hello";System.out.println(str4 + b1);
String str5 = str4 + b1;
String str6 = str4 + b1 + num1;
System.out.println(str6);//hellotrue10
//思考:如下的声明编译能通过吗?不能
//String str7 = b1 + num1 + str4;//如何将String类型的变量转换为基本数据类型?
String str8 = "abc";//不能考虑转换为基本数据类型的。int num2 = 10;
String str9 = num2 + ""; //"10"
//编译不通过
//int num3 = (int)str9;//如何实现呢?使用Integer类。暂时大家了解。
int num3 = Integer.parseInt(str9);
System.out.println(num3 + 1);
}
}
1.7进制的认识
熟悉 : 二进制 (以0B , 0b开头) , 十进制 , 八进制 (以0开头) , 十六进制 (以0x或0X开头) 的声明方式
二进制的理解 :
正数 : 原码 , 反码 , 补码三码合一
负数 : 原码 , 反码 , 补码不相同 , 理解他们三者的关系
计算机的底层使用补码的方式存储数据的
熟悉 : 二进制与十进制之间的转换
了解 : 二进制与八进制 , 十六进制的转换
1.8运算符(较常用的是重点)
1.8.1 算术运算符
1 . + - * / % ++(前后之分) --(前后之分)
/*
测试运算符的使用1:算术运算符的使用
1. + - + - * / % (前)++ (后)++ (前)-- (后)-- +
*/
class AriTest {
public static void main(String[] args) {
//*******************************
//除法: /
int m1 = 12;
int n1 = 5;
int k1 = m1 / n1;
System.out.println(k1);//2System.out.println(m1 / n1 * n1);//10
//*******************************
//取模(或取余): %
int i1 = 12;
int j1 = 5;
System.out.println(i1 % j1); //2//开发中,经常用来判断某个数num1能整除另外一个数num2。 num1 % num2 == 0
//比如:判断num1是否是偶数: num1 % 2 == 0
//结论:取模以后,结果与被模数的符号相同
int i2 = -12;
int j2 = 5;
System.out.println(i2 % j2); //-2int i3 = 12;
int j3 = -5;
System.out.println(i3 % j3); //2int i4 = -12;
int j4 = -5;
System.out.println(i4 % j4); //-2
//*******************************
//(前)++ :先自增1,再运算
//(后)++ :先运算,后自增1
int a1 = 10;
int b1 = ++a1;
System.out.println("a1 = " + a1 + ",b1 = " + b1); //a1 = 11,b1 = 11int a2 = 10;
int b2 = a2++;
System.out.println("a2 = " + a2 + ",b2 = " + b2); //a2 = 11,b2 = 10//练习1:
int i = 10;
//i++;
++i;
System.out.println("i = " + i);//11//练习2:
short s1 = 10;
//方式1://编译不通过
//s1 = s1 + 1;//s1 = (short)(s1 + 1);
//System.out.println(s1);//方式2:
s1++;
System.out.println(s1);//*******************************
//(前)-- :先自减1,再运算
//(后)-- :先运算,再自减1
//略
//结论:++ 或 -- 运算,不会改变变量的数据类型!//+ :连接符,只适用于String与其他类型的变量间的运算,而且运算的结果也是String类型。
}
}
1.8.2赋值运算符
- = , += , -= , *= , /= , %=
- 说明
①当等号两次数据不一致时,可以用强制类型转换和自动类型转换来处理
②支持连续赋值
③除了 = 可能改变数据类型 , 剩下这些操作不会改变变量本身的数据类型
class SetValueTest {
public static void main(String[] args) {//***********************************
int i = 5;long l = 10; //自动类型提升
byte b = (byte)i; //强制类型转换
//操作方式1:
int a1 = 10;
int b1 = 10;//操作方式2:连续赋值
int a2;
int b2;
//或合并:int a2,b2;
a2 = b2 = 10;System.out.println(a2 + "," + b2);
//操作方式3:
//int a3 = 10;
//int b3 = 20;int a3 = 10,b3 = 20;
System.out.println(a3 + "," + b3);//***********************************
//说明 += 的使用
int m1 = 10;
m1 += 5; //类似于m1 = m1 + 5;
System.out.println(m1);byte by1 = 10;
by1 += 5; //by1 = by1 + 5操作会编译报错。应该写为: by1 = (byte)(by1 + 5);
System.out.println(by1);
int m2 = 1;
m2 *= 0.1; // m2 = (int)(m2 * 0.1)
System.out.println(m2);//练习1:如何实现变量的值增加2。
//方式1:
int n1 = 10;
n1 = n1 + 2;
//方式2:推荐
int n2 = 10;
n2 += 2;//错误的写法:
//int n3 = 10;
//n3++++;//练习2:如何实现变量的值增加1。
//方式1:
int i1 = 10;
i1 = i1 + 1;
//方式2:
int i2 = 10;
i2 += 1;//方式3:推荐
int i3 = 10;
i3++; //++i3;}
}
1.8.3 比较运算符
- == , != , > , < , <= , >= , instanceof
- 说明:
①instanceof是判断引用数据类型是不是相同,比如说是不是同一个类,来判断,再来对这个类进行操作,一般需要重写equals方法.
②== , != , < , > , <= , >= 适用于基本数据类型 , (< , > , <= , >= 不适用于boolean类型)
③== , !=可以适用于引用数据类型
④区分 : == 与 =
1.8.4 逻辑运算符
1.& , && , | , || , ! , ^ ,
2.说明 :
①逻辑运算符针对的都是boolean类型的变量进行的操作
②逻辑运算符运算的结果也是boolean类型
③逻辑运算符常使用条件判断结构 , 循环结构中
class LogicTest {
public static void main(String[] args) {
/*
区分:& 和 &&
1、相同点:两个符号表达的都是"且"的关系。只有当符号左右两边的类型值均为true时,结果才为true。2、执行过程:
1)如果符号左边是true,则& 、&& 都会执行符号右边的操作
2)如果符号左边是false,则 & 会继续执行符号右边的操作
&& 不会执行符号右边的操作
3、开发中,我们推荐使用&&
*/
boolean b1 = true;
b1 = false;int num1 = 10;
if(b1 & (num1++ > 0)){
System.out.println("床前明月光");
}else{
System.out.println("我叫郭德纲");
}
System.out.println("num1 = " + num1);//
boolean b2 = true;
b2 = false;int num2 = 10;
if(b2 && (num2++ > 0)){
System.out.println("床前明月光");
}else{
System.out.println("我叫郭德纲");
}
System.out.println("num2 = " + num2);//********************************************
/*
区分:| 和 ||
1、相同点:两个符号表达的都是"或"的关系。只要符号两边存在true的情况,结果就为true.2、执行过程:
1)如果符号左边是false,则| 、|| 都会执行符号右边的操作
2)如果符号左边是true,则 | 会继续执行符号右边的操作
|| 不会执行符号右边的操作
3、开发中,我们推荐使用||
*/
boolean b3 = false;
b3 = true;int num3 = 10;
if(b3 | (num3++ > 0)){
System.out.println("床前明月光");
}else{
System.out.println("我叫郭德纲");
}
System.out.println("num3 = " + num3);//
boolean b4 = false;
b4 = true;int num4 = 10;
if(b4 || (num4++ > 0)){
System.out.println("床前明月光");
}else{
System.out.println("我叫郭德纲");
}
System.out.println("num4 = " + num4);
}
}
1.8.5位运算符
1.<< , >> , >>> , & , | , ^ , ~
1.8.6 条件运算符(三目运算符)
1.三目运算符 : (条件表达式) ? 表达式1 : 表达式2
2.说明 :
①条件表达式的结果是boolean类型
②如果条件表达式的结果是true , 则执行表达式1 , 反之表达式2
③表达式1和表达式2需要是相同的类型或能兼容的类型
④开发中 , 凡是可以使用条件运算符的位置 , 都可以改写为if - else
反之 : 能使用if - else , 不一定能改写为条件运算符
建议:二者都能用的情况下,用条件运算符,效率能高一点 .
1.8.7 运算符的优先级
如果想体现优先级较高 , 使用( )
我妈在编写一个执行语句时,不要出现太多的运算符
小拓展:
为什么Java中0.1 + 0.2 != 0.3 ?
计算机底层都是二进制 , 整数变为二进制都有一个具体的二进制值与他对应,但是小数就不一样了 , 没有一个具体的值与他对应 , (现在我们所用的都是IEEE 754标准 , 我也不太懂 , 感兴趣的可以自己了解) , 反正虽然这种方法很牛逼 , 但是还是不能突破物理的边界 , 仍然不能实现每一个十进制小数都有一个对应的二进制小数 , 正因如此 , 才出现了0.1 + 0.2 != 0.3 的问题