文章目录
-
-
本篇正式进入JAVA基础语法的学习
-
-
包括内容有注释、标识符、变量类型、关键词、运算符等基础知识
-
-
23 注释
-
24 标识符规则
-
25 Java中的关键字/保留字
-
26 变量的本质 声明格式和初始化问题
-
27 变量分类
-
28 常量和final
-
29 基本数据类型介绍(primitive data type)
-
30 整型变量和整型常量
-
31 浮点型变量(float、double)和BigDecima的使用
-
32 字符型类型-转义字符
-
32 布尔类型-if语句使用要点
-
33 运算符介绍
-
34 算术运算符 (二元、自增和自减)
-
36 赋值和赋值扩展运算符
-
37 关系运算符
-
38 逻辑运算符_短路运算详解
-
39 位运算符
-
40 字符串连接符
-
41 条件运算符
-
42 运算符优先级_逻辑与或优先问题
-
43 自动类型转换
-
44 强制类型转换
-
45 基本类型常见错误:溢出,L问题
-
45 使用Scanner获取键盘输入
-
-
-
本篇正式进入JAVA基础语法的学习
包括内容有注释、标识符、变量类型、关键词、运算符等基础知识
23 注释
注释内容不会出现在字节码文件中,即编译器编译时会自动跳过注释语句。
单行注释、多行注释、文档注释
文档注释以/**开头,*/结尾,包含说明性文字及一些JavaDoc标签(后期写项目时可以生成项目的API)
输入/**后直接回车即可,或者输入/*后直接回车也可。
其中多行注释可以用于代码的行内注释
24 标识符规则
- 标识符是对变量、类、方法以及包进行命名的。
- 必须以字母、下划线_、美元符号$开头,后面可任意组合字母、下划线、美元符号、数字
- 其他特殊符号不可用,如 #
- Java标识符区分大小写,且长度无限制
- 标识符不可以是Java的关键字
使用规范
-
表示类名的标识符,每个单词首字母大写,如 GodMan
-
表示方法和变量的标识符,第一个单词首字母小写,从第二个单词开始首字母大写,
如eat,eatFood,youKnowNothing ,这称为“驼峰原则”注意:Java不采用常用的ASCII字符集,而采用Unicode这样标准的国际字符集。因此 这里字母的含义不仅是英文,还包括汉字,但不建议用汉字定义标识符。
25 Java中的关键字/保留字
Java关键字是Java语言保留供内部使用的,如class用于定义类
注意:上述关键字不需刻意去记,从实战思维出发,随着学习深入,自然就非常熟悉了。
26 变量的本质 声明格式和初始化问题
变量本质上是“可操作的存储空间”,变量名对应系统分配的一块空间,空间位置确定下来,但里面存放的数值是不确定的,可以通过变量名来访问对应的存储空间,从而操作存储空间的值。
可以声明不同的数据类型变量,不同数据类型分配不同大小的空间,如int型只能存放整数,分配4个字节。
注:每个变量都有类型,可以是基本类型,也可以是引用类型。
变量名必须是合法的标识符
变量声明是一条完整的语句,每个声明必须以分号结束。
可以在一行中声明多个变量,如 int i ,j; 这种做法不提倡,因为降低了可读性。
27 变量分类
-
局部变量 (local variable):方法或语句块内部定义的变量,生命周期是从声明位置开始到方法或语句块执行完毕为止。
上图中age的生命周期仅限于括号内,salary的生命周期仅在整个main方法内。 -
成员变量(member variable 又叫实例变量):方法外部、类的内部定义的变量。从属于对象,生命周期伴随对象始终。如果不自行赋予初始值,会自动赋默认值如下:
-
静态变量(static variable 又叫类变量):使用static定义。从属于类,生命周期伴随类始终,从加载到卸载。在三种变量中周期最长,其次为成员变量,最短为局部变量。
三种变量大概如下图:
建议:不必在此过多纠结,学习面向对象时会重点讲解成员变量和静态变量
28 常量和final
-
常量通常指一个固定的值,例如1、2、3、‘a’、true、”helloWorld”等。
-
Java语言中主要利用关键字final来定义一个常量
-
常量一旦被初始化后不能载更改其值
老鸟建议: 所有变量、方法、类名:见名知意 类成员变量:首字母小写和驼峰原则:monthSalary 局部变量:首字母小写和驼峰原则 *常量:大写字母和下划线:MAX_VALUE *类名:首字母大写和驼峰原则:Man,GoodMan 方法名:首字母小写和驼峰原则:run(),runRun()
/**
* 常量测试
* @author Administrator
*
*/
public class TestConstant {
public static void main(String[] args) {
int age = 18;
age = 19; //这里改变了“age”的值却没有报错
final String NAME = "FengJixiang";
NAME = "喵喵宝宝"; //改变了变量name的值,这里报错了,因为是常量,不能改变
}
}
29 基本数据类型介绍(primitive data type)
分类:三大类八小类
:
注意:布尔型变量占1位,而不是1个字节,即1bit,而不是1Byte。其他均按字节计数。
引用数据类型占据4个字节,用来代表对象的地址。
与C相比,整型多了一个byte类型,占1个字节。
30 整型变量和整型常量
package 实验包;
/**
* 测试基本数据类型
* @author 喵喵宝宝
*
*/
public class TestPrimitiveDataType {
public static void main(String[] args) {
//测试整型变量
int a = 15;
int b = 015;//以0开头的为八进制
int c = 0x15;//以0x开头是16进制
int d = 0b1101;//以0b开头是二进制
System.out.println(b); //最后是十进制的输出结果: 5*8^0+1*8^1 = 13
System.out.println(c);//最后是十进制的输出结果: 5*16^0+1*16^1 = 21
System.out.println(d);//最后是十进制的输出结果: 1+2^2+2^3 = 13
//注意给变量赋值时不要超过其表数范围,如byte age = 300;肯定会编译错误
byte age = 30;
short salary = 30000;
int population = 2100000000;
// long globlePopulation = 7400000000; 这样会编译错误,因为整型常量默认是int类型,超出加L
long globlePopulation = 7400000000L;//后面加L表示这是一个long类型 常量
}
}
运行结:
13
21
13
31 浮点型变量(float、double)和BigDecima的使用
-
浮点型即带小数的数据
科学计数法:314e2 = 31400 314e-2 = 3.14
-
float类型尾数可精确到7位有效数据,经常难以满足需求。而double精确度约是float的两倍,又被称作双精度浮点型。
-
绝大部分应用程序采用double类型
-
浮点型常量默认类型也是double
在实践中学习:
package 实验包;
import java.math.*; //后面的类 BigDecimal所属的包
/**
* 测试浮点型
* @author 喵喵宝宝
*
*/
public class TestPrimitiveDataType2 {
public static void main(String[] args) {
/*
* float a = 3.14;这样肯定编译出错。
* 因为浮点型常量3.14默认类型是double类型,占8个字节,而float类型占4个字节
* 装不进去。因此要写成:float a = 3.14F;这里的F表示数据为float类型,占4个字节
* 也可以这样来强制转换 float a = (float)3.14;表示强制将默认的double转换成float
*
*/
float a = 3.14F; //这样便不会编译出错
double b = 6.28; //或 double b = 6.28D;这里的D可加可不加
double c = 628e-2; //e写成E也可,这个与上面的double b = 6.28等价
System.out.println(c); //c的输出为6.28
//注意:浮点数是不精确的,见下面的例子
float f = 0.1f;
double d = 1.0/10;
System.out.println(f == d);
/*上面的输出结果为false而不是true;
* 因为浮点数是不精确的,一定不要用于比较!
*/
//再看下面的例子
float d1 = 423432423f;
float d2 = d1 + 1;
if(d1 == d2) {
System.out.println("d1 == d2");//输出结果d1 == d2
}else {
System.out.println("d1!=d2");
}
//上面这一段运行会发现结果为d1==d2,这不符合实际,还是那句话,浮点数不精确,不要用于比较
/*
* 如果要比较,用java.math包下面的两个类,BigInteger实现任意精度的整数运算;
* BigDecimal实现任意精度的浮点运算(推荐,银行系统用到)
* 例子见下面
*/
System.out.println("*********************************************");//分割线
BigDecimal bd = BigDecimal.valueOf(1.0);// 用BigDecimal定义bd为精确值1.0
bd = bd.subtract(BigDecimal.valueOf(0.1));//bd自减一个精确值0.1
bd = bd.subtract(BigDecimal.valueOf(0.1));//bd自减一个精确值0.1
bd = bd.subtract(BigDecimal.valueOf(0.1));//bd自减一个精确值0.1
bd = bd.subtract(BigDecimal.valueOf(0.1));//bd自减一个精确值0.1
bd = bd.subtract(BigDecimal.valueOf(0.1));//bd自减一个精确值0.1
System.out.println(bd); //结果为0.5 精确值
System.out.println(1.0-0.1-0.1-0.1-0.1-0.1); //对比,直接减,结果为0.5000000000000001 非精确值
//这样一来用BigDecumal得到的精确值就可以比较了,见下面
BigDecimal bd2 = BigDecimal.valueOf(0.1);
BigDecimal bd3 = BigDecimal.valueOf(1.0/10.0);
System.out.println(bd2.equals(bd3));//使用这个类之后可以这样来比较,结果为true,说明二者都为精确值0.1
}
}
总结:
- 默认是double型
- 浮点数存在舍入误差,数字不能精确表示。如果需要进行不产生舍入误
差的精确数字计算,需要使用BigDecimal类
- 避免比较中使用浮点数,需要比较请使用BigDecimal类
32 字符型类型-转义字符
- char类型即字符型,占2个字节,Java中使用单引号表示字符常量
- 比如:’A’表示一个字符,”A”则表示含有一个字符的字符串。
- char用来表示Unicode编码表中的字符,Unicode编码设计来处理各种语言的文字,占两个字节,可允许有65536个字符。
转义字符:利用‘\’后面再加一个其他字符表示特殊含义。如表示退格、换行、回车等。
见下图:
测试代码:
package 实验包;
/**
* 测试字符类型
* @author 喵喵
*
*/
public class TestPrimitiveDataType3 {
public static void main(String[] args) {
char a = 'T';
char b = '尚'; //每个汉字也在Unicode编码中,每个汉字是一个字符
//Unicode具有0~65535之间的编码,通常可表示为'\u0000'~'\uFFFF'(十六进制),见下
char c = '\u0061';
System.out.println(c); //输出结果为a,说明字符a在Unicode中编码位置为0061
//转义字符
System.out.println('a'+'b'); //这里输出了一个数195,a代表的T和b代表的汉字会自动转化成对应数字
System.out.println(""+'a'+'b'); //前面加个空字符串,可以让后面都变成字符串,不变成数字,输出为ab
System.out.println(""+'a'+'\n'+'b'); //换行符测试 输出为 a 换行 b
System.out.println(""+'a'+'\t'+'b'); //制表符测试 输出为 a b
System.out.println(""+'a'+'\''+'b'); //单引号测试 输出为 a 'b
//以后我们学的字符串,其实就是字符序列,本质上就是字符的数组来表示的
//比如 char d = "ab"; 肯定输出不了因为char类型占两个字节,只能存放一个字符
String d = "ab";
System.out.println(d); //输出:ab ,这样就没问题了
}
}
32 布尔类型-if语句使用要点
boolean类型两个常量值为true和false,在内存中占一位而非一个字节,不可以用0和非0整数替代,这点与C语言不同。主要用于判断逻辑条件,用于程序流程控制。
测试代码
package 实验包;
/**
* 测试布尔类型
* @author 喵喵
*
*/
public class TestPrimitiveDataType3 {
public static void main(String[] args) {
boolean man = true;
if(man) {//建议不要写成man == true,因为容易写成man = true,就变成了赋值而非判断
System.out.println("男性");
}
}
}
33 运算符介绍
计算机语言编程经常会执行数学运算,因此需要提供运算符来操作变量。
分类如下,注意这些运算符都很重要。
34 算术运算符 (二元、自增和自减)
二元运算符:需要两个操作数才能完成运算的运算符
包括+ – * / %(取余或取模)
运算规则:
1.整数运算:
- 俩操作数有一个为long,结果为long
- 没有long时,结果为为int,即使全为byte,short,结果也是int
- 有一个为double,结果为double
- 只有两个操作数都为float,结果才为float
package 实验包;
/**
* 测试算术运算符
* @author Administrator
*
*/
public class TestOperator01 {
public static void main(String[] args) {
byte a = 1;
int b = 2;
long b2 = 3;
// byte c = a+b; 报错 因为结果应为int型
int c = a+b; //这样便不会报错
// int c2 = b2+b;报错,因为结果应为long型
float f1 = 3.14F;//不能写成float f1 = 3.14;
float d1 = b + b2;
double d2 = b + b2;
//上面两行均没有问题,因为浮点型表数范围更大,这里发生了自动类型转换
float d3 = f1 + 6.2; //报错,这里6.2默认为double类型,结果应为double
}
}
2.取模运算
- 操作数可以为浮点数。余数符号与左边操作数相同。如-7%3 = -1;
一元运算符:只需要一个操作数,如++、–
int b = a++;//先给b赋值,再自增1
int b = ++a;//先自增1,再给b赋值
36 赋值和赋值扩展运算符
常见扩展运算符:
int a = 3;//赋值
int b = 4;//赋值
a+=b; //a = a+b
System.out.println("a" = +a + "\nb="+b);
//输出结果为:a = 7 换行 b = 4
37 关系运算符
常见的关系运算符:
注意:
= 和== 不一样
==和!= 所有数据类型(基本和引用)都可以使用
> < '>=' '<=' 仅针对数值类型和char类型(会自动转化成对应的数值)
int a = 3;
System.out.println(a == 3); //输出true
System.out.println(a != 3);//false
System.out.println(a <5);//true
char b = 'a';
char b2 = 'c';
System.out.println(int(b)); //强制转换为int型,输出97
System.out.println(0+b); //0是int型,于是结果为int型,97
System.out.println(b<b2);
//先转化成ASCII码对应的数值再比较,97<99,输出true
38 逻辑运算符_短路运算详解
逻辑运算符的操作数和运算结果都是boolean值,主要包括与、或、非等逻辑运算。见下图:
注意:
- 异或:当全为真或全为假结果为false,一真一假则结果为true。
- 短路与与逻辑与、短路或与逻辑或,前后的差别就是短路运算只要前面的操作数能确定结果的话直接不看后面得出结果,短路运算效率更高,因此编程一般用短路运算。
boolean b1 = true; boolean b2 = false;
System.out.println(b1&b2);//结果为false
System.out.println(b1|b2);//结果为true
System.out.println(b1^b2);//前后不一样,结果为true
System.out.println(!b2);//结果为true
//短路
//int c = 3/0;//编译出错,0不能做除数
boolean b3 = 1>2 & 2<(3/0);
System.out.println(b3);//编译出错,因为上面b3是逻辑与,前后都做了计算
boolean b4 = 1>2 && 2<(3/0); //短路与
System.out.println(b4);
/*结果为false,短路与前面判断为false后面不再判断,
这也是短路运算的弊端,后面未判断的可能是错误代码*/
39 位运算符
位运算指的是进行二进制位的运算包括与、或、异或、取反、左移、右移等。具体见下图:
比如:3化成二进制位:0011 4:0100
按位与&:0000 按位或|:0111
按位异或^:0111
左移一位相当于乘以2,右移一位相当于除以2
如int b = 3<<2;相当于3
2
2
int d = 12 >> 2;相当与12/2/2 这样乘除运算效率高
取反符号:~
vpackage 实验包;
public class 位运算符 {
public static void main(String[] args) {
int a = 3;//0011
int b = 4;//0100
System.out.println(a&b);//0000
System.out.println(a|b);//0111
System.out.println(a^b);//0111
System.out.println(~a);//取反 1100
//上面的输出结果都是十进制 但运算的时候是先转成二进制运算的
/*
* 取反:正整数x(包括0)的按位取反结果为-(x+1),负整数x按位取反结果为|x+1|,
* 运算过程:0011->取反:1100->首位是1,表示负数->0011+1 = 0100(这是源码)
* ->加负号:-0100->-4
*/
//移位运算
int c = 3<<2;//3*2*2
System.out.println(c);//12
System.out.println(12>>1);//12/2 = 6
System.out.println(12>>2);//12/2/2 = 3
}
}
40 字符串连接符
即“+”,+的左右两边操作数只要有一个是字符串(string)类型,系统会将另外一个操作数转换为字符串然后再进行连接,如3+“4” ->输出结果为:34 而不是7
package 实验包;
public class 字符串连接符 {
public static void main(String[] args) {
// TODO Auto-generated method stub
String a = "3";
int b = 4;
int c = 5;
System.out.println(a+b);//字符串:34
System.out.println(b+c);//整型:9
System.out.println(a+b+c);//字符串:345
System.out.println(b+c+a);//字符串:93 不是453 因为先计算前面的得到int型9.再跟字符型3做运算
//字符与字符串的区别
char d = 'a';
System.out.println(d); //输出字符a
System.out.println(d+4);//输出101,因为a的ASCII码是97,97+4 = 101
}
}
41 条件运算符
语法格式: x ? y:z
x是boolean类型,若是true返回y,若是false,返回z
package 实验包;
//条件运算符或三元运算符
public class 条件运算符 {
public static void main(String[] args) {
int score = 80;
String type = score < 60 ? "不及格" :"及格";
System.out.println(type);
//等同于下面的判断语句
if(score < 60) {
System.out.println("不及格");
}else {System.out.println("及格");
}
//复杂一点的判断如下
int x = -100;
System.out.println(x > 0? 1:(x==0 ? 0:-1));
//结果为-1,x>0为false,输出后面的内容,判断后面括号中x==0为false,输出后面的内容为-1,将这个-1抛到上一层,即输出-1
}
}
42 运算符优先级_逻辑与或优先问题
注意:
- 上面优先级不需刻意背,用到时直接用小括号来组织。
- 逻辑非 > 逻辑与 > 逻辑或
- a || b && c等价于 a || (b&&c)
- 括号 > ±! > ++ – > 算术运算符>关系运算符>逻辑运算符>赋值运算符
43 自动类型转换
指的是容量小的数据类型可以自动转换为容量大的数据类型。
上图中,箭头指向表示可以发生自动类型转换,蓝色箭头表示转换时可能会有精度的损失。
可以将整型常量直接赋值给byte、short、char等类型变量,而不需进行强制类型转换,只要不超出其表数范围即可。
自动类型转换特例:
short b = 12; //合法。虽然12初始为int型,但是由于12未超过short的表数范围,因此可以自动转换为
short b = 1234567;//不合法。1234567超出short类型的表数范围(30000左右)。
public class 自动类型转换 {
public static void main(String[] args) {
int a = 324;
long b = a; //int型自动转换为long型并赋值给b
double d = b;//long型自动转换为double型,赋值给d。这里有精度的损失
// a = b; 编译错误,long型不能转为int型,大不能转小
// long e = 3.23F 编译错误,float不能转为long
float f = 234324L; //long型自动转为float型
//特例
byte b2 = 123;//byte的范围是-128~127 int转为了byte
//如果 byte b2 =1230;编译错误,超出了表数范围
//总的原则:容量小的向容量大的转换
}
}
44 强制类型转换
自动类型转换不起作用时,比如要把double转为int,就用到强制类型转换。
语法格式:在数值前面的括号中输入想强制转化为的类型
double x = 3.14;
int nx = (int)x; //将double强制转换为int,准换后值变为整数3,舍去了小数部分
char c = 'a';
int d = c + 1; //a的ASCII码97,转化成int,d为98
System.out.println(nx); //3
System.out.println(d);//98
System.out.println((char)d); //强转成char,输出为:b
45 基本类型常见错误:溢出,L问题
- 操作比较大的数时,要留意是否溢出
- 不要命名名字为l的变量,l容易和1混淆。long类型使用大写L而不要用小写。
int money = 1000000000; //10亿
int years = 20;
int total = money * years;
System.out.println("total = " + total);
//+是字符连接符,返回的total是负数,因为超出了int的范围(约21亿),发生溢出错误
long total1 = money * years;
System.out.println("total1 = " + total1);
/*返回结果仍然是个负数,虽然long的范围大,但先计算右边,结果默认是int型,首先发生溢出错误得到一个错误的结果载把这个错误结果赋值给了long型变量total1*/
//不发生溢出错误的写法见下:
long total2 = money * (long)years;
//将其中一个强制转为long型,结果就为long,不发生溢出错误
System.out.println("total2 = " + tota2);
//不确定是否会溢出(溢出不好确定因为并不会编译报错),就先转化再赋值,比如下面这个
long total3 = 34 * 3223 * years * 223423;
//上面这个不确定是否会超出int范围溢出,改正如下
long total3 = 34L * 3223 * years * 223423;//在其中一个数字后加L转换为long型,则不会发生溢出了
//命名问题 L问题
int l = 2; //名字分不清是L还是1
long a = 2345l;//建议用大写L后缀,否则易看成1
System.out.println(l + 1);
45 使用Scanner获取键盘输入
使用键盘输入可以使程序的人机交互性更强,更有趣味性。
package 实验包;
//Scanner是系统默认包之外的类,因此必须导入其所在的包,才能导入这个类
import java.util.Scanner;
/**
* 测试获得键盘输入
* @author Administrator
*
*/
public class 测试Scanner键盘输入 {
public static void main(String[] args) {
//先创建一个Scanner对象
Scanner scanner = new Scanner(System.in);//导入的System.in是一个IO流对象
System.out.println("请输入你的名字:");
String name = scanner.nextLine();
//输入内容用字符串变量来接收,nextLine可以获得输入的这一行字符串,并赋值给字符串变量name
System.out.println("请输入你的爱好:");
String favor = scanner.nextLine();
System.out.println("请输入你的年龄:");
int age = scanner.nextInt();//用int型变量接收输入内容,nextInt可以获得输入的变量并赋值给age
//如果是小数,就改成nextDouble
//打印出来
System.out.println("**********************分割线**********************");
System.out.println(name);
System.out.println(favor);
System.out.println("来到地球的天数:" + age*365);
System.out.println("离开地球的天数:" +( 72-age)*365);//72作为人生平均年龄
}
}
输入和输出结果:
请输入你的名字:
老高
请输入你的爱好:
敲代码
请输入你的年龄:
33
**********************分割线**********************
老高
敲代码
来到地球的天数:12045
离开地球的天数:14235