Java基本语法
01-基础语法上-变量和数据类型
2021-05-23 420 1
简介 基础语法上-包含的内容关键字、保留字、标识符、命名规范、变量和数据类型,自动类型提升、强制类型转换、字符串简单介绍、进制
1. 保留字、关键字 Keyword
关键字(keyword)的定义和特点
定义: 被Java语言赋予了特殊含义,用做专门用途的字符串(单词)
特点: 关键字中所有字母都为小写
Java保留字:现有Java版本尚未使用, 但以后版本可能会作为关键字使用。自己命名标识符时要避免使用这些保留字 goto 、 const
官方地址: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html
goto const 作为保留字, 使用的时候注意, 现在未使用,但是以后可能会使用
true false null 作为字面值, 不是关键字,但是不能用作标识符
官方的解释: true, false, and null might seem like keywords, but they are actually literals; you cannot use them as identifiers in your programs.
2. 标识符: identifier
类名、变量名、方法名、接口名、包名
定义合法标识符规则:
由26个英文字母大小写,0-9 ,_或 $ 组成
新建一个 IdtTest.java 文件,编辑如下内容:
class test_1_${
public static void main(String[] args) {
}
}
类名 test_1_$ 符合上述规则,是允许的,但是还有其他规则,还要遵循下面的几项规则
数字不可以开头。
class 2test_1_${
public static void main(String[] args) {
}
}
类名以数字2开头, 我们使用javac编译
IdtTest.java:1: 错误: 需要<标识符>
class 1test_1_${
^
IdtTest.java:1: 错误: 需要<标识符>
class 1test_1_${
^
2 个错误
请按任意键继续. . .
不可以使用关键字和保留字,但能包含关键字和保留字。
class static{
public static void main(String[] args) {
}
}
类名以关键字static命名,使用 javac 编译
IdtTest.java:1: 错误: 需要<标识符>
class static{
^
IdtTest.java:2: 错误: 非法的表达式开始
public static void main(String[] args) {
^
IdtTest.java:2: 错误: 非法的表达式开始
public static void main(String[] args) {
^
IdtTest.java:2: 错误: 需要';'
public static void main(String[] args) {
^
IdtTest.java:2: 错误: 需要 '.class'
public static void main(String[] args) {
^
IdtTest.java:2: 错误: 需要';'
public static void main(String[] args) {
^
IdtTest.java:5: 错误: 解析时已到达文件结尾
}
^
7 个错误
请按任意键继续. . .
Java中严格区分大小写,长度无限制。
class Static{
public static void main(String[] args) {
}
}
类名以关键字static命名的时候,使用 javac 编译错误,我们将 static 改为 Static之后,编译通过(Java语言是严格区分大小写的)
class Static____________________11111111122222222222223333333333333333344444444444555555555555{
public static void main(String[] args) {
}
}
这样也是编译通过的, 起了一个名字很长的类名, Static____________________11111111122222222222223333333333333333344444444444555555555555 仅仅为了测试
标识符不能包含空格。
class Static Person{
public static void main(String[] args) {
}
}
这个很容易理解, 有空格就是两个单词了, class 后需要跟类名, 既然类名是 Static了, 后面的 Person是什么呢?
IdtTest.java:1: 错误: 需要'{'
class Static Person{
^
1 个错误
请按任意键继续. . .
建议多写一下错误的代码, 看看报错信息, 错误信息看的多了, 工作中遇到问题的时候,每个错误信息,你就大致知道是什么原因导致的, 解决问题也就得心应手了。
3. 命名规范
规范与规则不同 ,这就比如一个是法律一个是道德,规则(法律)必须遵守, 规范可以不遵循,规范是为了让代码可读性更高
包名:多单词组成时所有字母都小写: xxxyyyzzz
类名、接口名:多单词组成时,所有单词的首字母大写: XxxYyyZzz (大驼峰)
变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个 单词首字母大写: xxxYyyZzz (小驼峰)
常量名:所有字母都大写。多单词时每个单词用下划线连接: XXX_YYY_ZZZ
注意1:在起名字时,为了提高阅读性,要尽量有意义,“见名知意”。
class AA{
}
这里的类AA是干什么呢?
注意2: java采用unicode字符集,因此标识符也可以使用汉字声明,但是不建议使用。
class 类名{
}
int 学号 = 1003;
System.out.println(学号);
这样不报错,但是不建议标识符中有汉字。
总结
不遵循规范,可能会经常犯错误,比如别人都遵循规范写代码, 类名大驼峰,你的类名是小写的,那么别人看你的代码就可能看不懂, 你引用别人写好的类的时候,不知道所引用的标识符到底是个类名还是个变量名。 不遵循规范,工作中会被鄙视,强烈建议大家一定要遵循代码规范,就当这个规范是“规则”吧。
4. 变量
基本数据类型
基本数据类型变量间转换
基本数据类型与String间转换
进制与进制间的转换
变量的概念:
内存中的一个存储区域
该区域的数据可以在同一类型范围内不断变化
变量是程序中最基本的存储单元。包含变量类型、变量名和存储的值(一些语言是没有变量的类型的 比如 JS Python等语言,直接写个名字就可以识别到类型,运算时可以自动隐式转换) Java是强类型的语言, JS等是弱类型的语言。
变量的作用:
用于在内存中保存数据
//VariableTest.java public class VariableTest{ public static void main(String[] args){ // 变量的定义,这里的=是赋值符号,不是我们数学中的 等于号 int age = 23; // 变量的使用 System.out.println(age); // 变量的声明 int number; // 变量的赋值 number = 24; // 变量的使用 System.out.println(number); } }
使用变量注意:
Java中每个变量必须先声明,后使用
使用变量名来访问这块区域的数据,使用变量的时候,变量必须已经初始化。
//VariableTest1.java public class VariableTest1{ public static void main(String[] args){ // 变量未定义就使用,报错 System.out.println(number); } } /* VariableTest1.java:4: 错误: 找不到符号 System.out.println(number); ^ 符号: 变量 number 位置: 类 VariableTest1 1 个错误 */
//VariableTest2.java public class VariableTest2{ public static void main(String[] args){ int number; // 变量未初始化就使用,报错 System.out.println(number); } } /* VariableTest2.java:6: 错误: 可能尚未初始化变量number System.out.println(number); ^ 1 个错误 请按任意键继续. . . */
Java语言中的变量,声明后必须初始化,否则无法使用, 这与C/C++,JS、Python不同,很多高级Java程序员,都不知道这个事情,再次说下基础很重要。
变量的作用域:其定义所在的一对{ }内
变量只有在其作用域内才有效
同一个作用域内,不能定义重名的变量
//VariableTest3.java public class VariableTest3{ public static void main(String[] args){ { int number = 24; //变量都定义在其作用域内。在作用域内,它是有效的。换句话说,出了作用域,就失效了 //同一个作用域内,不可以声明两个同名的变量 double number = 22.22; } // 变量 number 作用域在 上面的 {} 内 System.out.println(number); } } /* VariableTest3.java:7: 错误: 已在方法 main(String[])中定义了变量 number double number = 22.22; ^ VariableTest3.java:10: 错误: 找不到符号 System.out.println(number); ^ 符号: 变量 number 位置: 类 VariableTest3 2 个错误 请按任意键继续. . . */
5. 数据类型
js中变量不需要指定类型, 是弱类型的
java 、c、c++需要变量指定类型 是强类型
变量需要先声明、再初始化,才能被使用, 否则会报错? 为什么 TODO
比如
int var;
System.out.println(var) ; // 此时报错
6. 整型
整数类型:byte、short、int、long
Java各整数类型有固定的表数范围和字段长度,不受具体OS的影响,以保证java程序的可移植性。
java的整型常量默认为int 型,声明long型常量须后加‘l’或‘L’
java程序中变量通常声明为int型,除非不足以表示较大的数,才使用long
类型 占用存储空间表数范围
byte 1字节 =8bit位 -128 ~ 127
short 2字节 -2^15~2^15-1
int 4字节 -2 ^31~ 2^31-1 (约21亿)
long 8字节 -2^63~ 2^63-1
问题: 500MB 1MB = 1024KB 1KB= 1024B B = byte ? bit?
B 是字节byte
bit: 计算机中的最小存储单位。byte:计算机中基本存储单元。
//VariableTest4.java public class VariableTest4{ public static void main(String[] args){ byte b1 = 127; byte b2 = -128; System.out.println(b1); System.out.println(b2); } }
// VariableTest5.java public class VariableTest5{ public static void main(String[] args){ byte b1 = 128; System.out.println(b1); } } /* 这里的byte 范围是 -128 ~ 127 ,赋值一个 128,超出范围,报错。 VariableTest5.java:5: 错误: 不兼容的类型: 从int转换到byte可能会有损失 byte b1 = 128; ^ 1 个错误 请按任意键继续. . . */
// VariableTest6.java class VariableTest6{ public static void main(String[] args) { // 声明long型变量,必须以"l"或"L"结尾 // 通常,定义整型变量时,使用int型。 short s1 = 128; int i1 = 1234; long l1 = 3414234324L; System.out.println(l1); } }
7. 浮点型:
浮点类型:float(4字节)、double(8字节)
与整数类型类似,Java 浮点类型也有固定的表数范围和字段长度,不受具体操作系统的影响。
浮点型常量有两种表示形式:
十进制数形式:如:5.12 512.0f .512 (必须有小数点)
科学计数法形式:如:5.12e2 512E2 100E-2
float:单精度,尾数可以精确到7位有效数字。很多情况下,精度很难满足需求。
double:双精度,精度是float的两倍。通常采用此类型。
Java 的浮点型常量默认为double型,声明float型常量,必须后加‘f’或‘F’。
类型 占用存储空间表数范围
单精度float 4字节 -3.403E38 ~ 3.403E38
双精度double 8字节 -1.798E308 ~ 1.798E308
因为浮点型有bit位是用来表示, E表示10的多少次方,因此, float(4字节)比long(8字节)表示的范围还要大。
Java代码中的 1.23 默认是double类型, 而 123 默认为int类型。
// VariableTest7.java public class VariableTest7{ public static void main(String[] args){ // 浮点型:float(4字节) \ double(8字节) // 浮点型,表示带小数点的数值 // float表示数值的范围比long还大 double d = 1222.22; System.out.println(d); // 定义float类型变量时,变量要以"f"或"F"结尾 float f = 1222.33F; System.out.println(f); // 通常,定义浮点型变量时,使用double型。 } }
8. 字符类型:char
char 型数据用来表示通常意义上“字符”(2字节)
Java中的所有字符都使用Unicode编码,故一个字符可以存储一个字母,一个汉字,或其他书面语的一个字符(Unicode编码就是用2个字节将世界上的所有文字统一进行编码)。
字符型变量的三种表现形式:
字符常量是用单引号(‘ ’)括起来的单个字符。例如:char c1 = 'a'; char c2 = '中'; char c3 = '9';
如果写为 char = '' 那么编译报错, char类型能且只能放一个字符, 不能不放空字符
// VariableTest8.java class VariableTest8 { public static void main(String [] args){ //3. 字符型:char (1字符=2字节) //① 定义char型变量,通常使用一对'',内部只能写一个字符 char c1 = 'A'; char c2 = 'AB'; // 不能存两个字符,即使是英文字符 char c3 = ''; // 不能存空字符 } } /* VariableTest8.java:8: 错误: 未结束的字符文字 char c2 = 'AB'; ^ VariableTest8.java:8: 错误: 未结束的字符文字 char c2 = 'AB'; ^ VariableTest8.java:8: 错误: 不是语句 char c2 = 'AB'; ^ VariableTest8.java:9: 错误: 空字符文字 char c3 = ''; ^ VariableTest8.java:9: 错误: 未结束的字符文字 char c3 = ''; ^ VariableTest8.java:9: 错误: 需要';' char c3 = ''; ^ VariableTest8.java:11: 错误: 解析时已到达文件结尾 } ^ 7 个错误 */
Java中还允许使用转义字符‘\’来将其后的字符转变为特殊字符型常量。
例如:char c3 = ‘\n’; // '\n'表示换行符
直接使用Unicode值来表示字符型常量:‘\uXXXX’。其中,XXXX代表
一个十六进制整数。如:\u000a 表示\n。
char类型是可以进行运算的。因为它都对应有Unicode码。
Unicode
乱码:世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。
Unicode:一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,使用Unicode 没有乱码的问题。
如果把各种文字编码形容为各地的方言,那么Unicode就是世界各国合作开发的一种语言。
在这种语言环境下,不会再有语言的编码冲突,在同屏下,可以显示任何语言的内容,这就是Unicode的最大好处。 就是将世界上所有的文字用2个字节统一进行编码。那样,像这样统一编码,2个字节就已经足够容纳世界上所有的语言的大部分文字了。
Unicode 的缺点:Unicode 只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储:无法区别Unicode 和ASCII:计算机无法区分两个字节表示一个符号还是分别表示两个符号。
Unicode字符集可以简写为UCS, UCS分为两种, UCS-2用两个字节编码,UCS-4用4个字节编码。
我们可以定义一个char类型的数据赋值为'庆','庆'使用utf-8编码后为:e5ba86,不错是三个字节,三个字节怎么赋值给只占两个字节的char类型变量呢? 可是事实是确实可以赋值的:char test = '庆'; 确实编译器没有报错,咋回事呢?这里就是大家的误区了。其实'庆'使用utf-16进行编码无论是大尾序utf-16BE(5E86)还是使用小尾序utf-16LE(865E)进行编码都是占用两个字节 也就是一个字符的。 所以,我们要了解一个事实就是JVM中对char是使用UTF-16编码的。使用UTF-16的好处是大部分字符都能以固定两个字节存储,但是这样的坏处就是对于英文字符存储就造成浪费。 为了解决这个问题,Java9以后对字符串做了优化,对于字符串里面都是拉丁字母或者ASCII码中的字符,不使用UTF-16编码存储,而是使用byte存储,这样可以省一部分空间。
// VariableTest9.java class VariableTest9{ public static void main(String[] args) { // char 类型变量可以存放 Unicode 编码的字符, char c1 = '1'; char c2 = '中'; char c3 = 'ス'; System.out.println(c1); System.out.println(c2); System.out.println(c3); //② 表示方式:1.声明一个字符 2.转义字符 3.直接使用 Unicode 值来表示字符型常量 char c5 = '\n';//换行符 c5 = '\t';//制表符 System.out.print("hello" + c5); System.out.println("world"); char c6 = '\u0043'; } }
了解UTF-8
UTF-8 是在互联网上使用最广的一种Unicode 的实现方式。
UTF-8 是一种变长的编码方式。它可以使用1-6 个字节表示一个符号,根据
不同的符号而变化字节长度。
UTF-8的编码规则:
对于单字节的UTF-8编码,该字节的最高位为0,其余7位用来对字符进行编码(等同于
ASCII码)。
对于多字节的UTF-8编码,如果编码包含n 个字节,那么第一个字节的前n 位为1,第一
个字节的第n+1 位为0,该字节的剩余各位用来对字符进行编码。在第一个字节之后的
所有的字节,都是最高两位为"10",其余6位用来对字符进行编码。
Windows下默认是 GBK字符集
Java代码设置为 UTF-8不能相互转换, EditPlus设置为 ANSI,就是GBK字符集
9. 15 boolean类型
数据只允许取值true和false,无null。
不可以使用0或非 0 的整数替代false和true,这点和C语言不同。
Java虚拟机中没有任何供boolean值专用的字节码指令, Java语言表达所操作的
boolean值,在编译之后都使用java虚拟机中的int数据类型来代替: true用1表示, false
用0表示。 ———《java虚拟机规范 8版》
//VariableTest10.java class VariableTest10 { public static void main(String[] args) { //布尔型:boolean //① 只能取两个值之一:true 、 false //② 常常在条件判断、循环结构中使用 boolean bb1 = true; System.out.println(bb1); boolean isMarried = true; if(isMarried){ // 输出特殊字符 引号 和 \n System.out.println("\"is\" true \\n"); }else{ System.out.println("is false"); } } }
10. 15-16 自动类型提升
结论:当容量小的数据类型的变量与容量大的数据类型的变量做运算时,结果自动提升为容量大的数据类型。
容量是指 数的范围, 而不是内存中占用多少字节(float的容量大于long的容量)
byte 、char 、short --> int --> long --> float --> double
// VariableTest11.java public class VariableTest11{ public static void main(String [] args) { byte b1 = 2; int i1 = 129; //byte b2 = b1 + i1;//编译不通过 int i2 = b1 + i1; long l1 = b1 + i1; System.out.println(i2); float f = b1 + i1; System.out.println(f); short s1 = 123; double d1 = s1; System.out.println(d1);//123.0 } } /* 131 131.0 123.0 */
注意:当byte、char、short三种类型的变量做运算时,结果为int型(三者运算的时候,经常出现超出范围的情况,所以转换为int,int和int计算的时候,也有超范围的情况,但是情况发生的少)
// VariableTest12.java public class VariableTest12{ public static void main(String[] args) { char c1 = 'a';//97 int i3 = 10; int i4 = c1 + i3; System.out.println(i4); short s2 = 10; //char c2 = c1 + s2;//编译不通过 byte b2 = 10; //char c3 = c1 + b2;//编译不通过 //short s3 = b2 + s2;//编译不通过 //short s4 = b1 + b2;//编译不通过 } } /* 以上的报错都为: 从int 转换为 xxx可能会有损失... 错误: 不兼容的类型: 从int转换到char可能会有损失 */
说明:此时的容量大小指的是,表示数的范围的大和小。比如:float容量要大于long的容量
有多种类型的数据混合运算时,系统首先自动将所有数据转换成容量最大的 那种数据类型,然后再进行计算。
byte,short,char之间不会相互转换,他们三者在计算时首先转换为int类型。 三种数据类型+-时很容易超出计算范围,所以...
boolean类型不能与其它数据类型运算。
当把任何基本数据类型的值和字符串(String)进行连接运算时(+), 基本数据类型的值将自动转化为字符串(String)类型。
11. 强制类型转换
强制类型转换:自动类型提升运算的逆运算。
1.需要使用强转符:()
2.注意点:强制类型转换,可能导致精度损失。
// VariableTest13.java public class VariableTest13{ public static void main(String[] args) { double d1 = 12.9; //精度损失举例 int i1 = (int)d1;//截断操作 System.out.println(i1); //没有精度损失 long l1 = 123; short s2 = (short)l1; //精度损失举例 int i2 = 128; byte b = (byte)i2; System.out.println(b);//-128 } }
特别的说明, 代码中有注释,可以详细查看注释说明
// VariableTest14.java public class VariableTest14{ public static void main(String [] args) { //1.编码情况1: long l = 123213; // 没加L 把123213当int类型 System.out.println(l); //编译失败:过大的整数 //long l1 = 21332423235234123; // 没加L 把 21332423235234123 当int类型,超出int long l1 = 21332423235234123L; //**************** //编译失败 //float f1 = 12.3; // 12.3 默认为 double float f1 = (float)12.3; //2.编码情况2: //整型常量,默认类型为 int 型 //浮点型常量,默认类型为 double 型 byte b = 12; //byte b1 = b + 1;//编译失败 //float f1 = b + 12.3;//编译失败,需要 double 类型接收 f1 } }
12. 字符串类型: String
String属于引用数据类型,翻译为:字符串
String不是基本数据类型,属于引用数据类型
声明String类型变量时,使用一对"", 使用方式与基本数据类型一致。例如: String str = “abcd”; ,使用双引号, char使用的是单引号
// StringTest.java public class StringTest { public static void main(String[] args) { String s1 = "hello"; // char c1 = ''; // 错误 : StringTest.java:5: 错误: 空字符文字, char 类型变量必须放一个字符 String s2 = ""; // 空字符串 } }
一个字符串可以串接另一个字符串,也可以直接串接其他类型的数据。例如:
str = str + “xyz” ;
int n = 100;
str = str + n;
String可以与其他8中数据类型做运算, 连接符 + 来进行运算。 8种数据类型,是包含了 boolean类型,运算的结果是 String 类型
+ 左右两边如果有String类型的变量, 那么 + 就是连接运算, 如果两边都不是String,那么+就是加法运算
//字符串、char、int 类型变量做加法或者连接运算的练习 char c = 'a';//97 A:65 int num = 10; String str = "hello"; System.out.println(c + num + str);//107hello System.out.println(c + str + num);//ahello10 System.out.println(c + (num + str));//a10hello System.out.println((c + num) + str);//107hello System.out.println(str + num + c);//hello10a
String str1 = 4; //判断对错: no String str2 = 3.5f + “”; //判断str2对错: yes System.out.println(str2); //输出: ”3.5” System.out .println(3+4+“Hello!”); //输出: 7Hello! System.out.println(“Hello!”+3+4); //输出: Hello!34 System.out.println(‘a’+1+“Hello!”); //输出: 98Hello! System.out.println(“Hello”+‘a’+1); //输出: Helloa1
1) short s = 5; s = s-2; //判断: no 2) byte b = 3; b = b + 4; //判断: no b = (byte)(b+4); //判断: yes 3) char c = ‘a’; int i = 5; float d = .314F; double result = c+i+d; //判断: yes 4) byte b = 5; short s = 3; short t = s + b; //判断: no // 判断是否能通过编译
13. 22 进制
世界上分10种人,认识1的人和不认识0的人。
对于整数,有四种表示方式:
二进制(binary): 0,1 ,满2进1.以0b或0B开头。
十进制(decimal): 0-9 ,满10进1。
八进制(octal): 0-7 ,满8进1. 以数字0开头表示。
十六进制(hex): 0-9及A-F,满16进1. 以0x或0X开头表示。此处的A-F不区分大小写。
如: 0x21AF +1= 0X21B0
Java整数常量默认是int类型,当用二进制定义整数时,其第32位是符号位;当是long类型时,二进制默认占64位,第64位是符号位
二进制的整数有如下三种形式:
原码:直接将一个数值换成二进制数。最高位是符号位
负数的反码:是对原码按位取反,只是最高位(符号位)确定为1。
负数的补码:其反码加1。
计算机以二进制补码的形式保存所有的整数。
正数的原码、反码、补码都相同
负数的补码是其反码+1
为什么要使用原码、反码、补码表示形式呢?
计算机辨别“符号位”显然会让计算机的基础电路设计变得十分复杂! 于是
人们想出了将符号位也参与运算的方法. 我们知道, 根据运算法则减去一个正
数等于加上一个负数, 即: 1-1 = 1 + (-1) = 0 , 所以机器可以只有加法而没有
减法, 这样计算机运算的设计就更简单了。
进制的基本转换
十进制 二进制互转
二进制转成十进制 乘以2的幂数
十进制转成二进制 除以2取余数
二进制 八进制互转 二进制三位一组
二进制 十六进制互转 二进制4位一组
十进制 八进制互转 与二进制类似
十进制 十六进制互转 与二进制类似
13 思考题
1. 标识符的命名规则有哪些?
2. 标识符的命名规范有哪些?
3. Java变量按照数据类型怎么划分?并指出Java的基本数据类型有哪8种,并指出各自占用的内存空间大小
4. 说明基本数据类型变量之间自动类型提升的运算规则。
5. 说明基本数据类型变量之间强制类型转换的使用规则和强转可能出现的问题。
1. 标识符的命名规则有哪些? 不遵守,编译不通过。
答案
1. 由26个英文字母大小写,0-9 ,_或 $ 组成
区分大小写
不能使用关键字和保留字
不能包含空格
数字不能开头
2. 标识符的命名规范有哪些?不遵守,编译运行都可以通过
包名:xxxyyyzzz
类名、接口名:XxxYyyZzz
变量名、方法名:xxxYyyZzz
常量名:XXX_YYY_ZZZ
3. Java变量按照数据类型怎么划分?并指出Java的基本数据类型有哪8种,并指出各自占用的内存空间大小
byte(1字节) short(2字节) int(4字节) long(8字节)
char(2字节)
float (4字节)double(8字节)
boolean(底层还是1和0,是int类型)
引用数据类型:类(比如String)、接口、数组
4. 说明基本数据类型变量之间自动类型提升的运算规则。
byte、short、char -àint àlong àfloat àdouble
5. 说明基本数据类型变量之间强制类型转换的使用规则和强转可能出现的问题。
容量大 -> 容量小
使用强转符:()
精度损失。