Java语言也和其他编程语言一样,使用标识符作为变量、对象的名字,也提供了系列的关键字用以实现特别的功能。
Java 语言里的分号(;)、花括号({})、方括号([])、圆括号(())、空格、圆点(.)都具有特殊的分隔作用,因此被统称分隔符。
Java 语言里对语句的分隔不是使用回车来完成的,Java 语言采用分号 ( ; ) ;作为语句的分隔。因此,每个Java 语句必须使用分号作为结尾。Java 程序允许行书写多个语句,每个语句之间以分号隔开即可,一个语句也可以跨多行,只要在最后结束的地方使用分号结束即可。例如,下面语句都合法的Java语句。
int age = 25; String name = "李刚"
String hello = "你好!" +
"Java";
值得指出的是, Java 语句可以跨越多行书写,但一个字符串、变量名不能跨越多行。例如 下面的Java 语句是错误的。
// 字符串不能跨越多行
String a = "dddddd
xxxxxx";
// 变量名不能跨越多行
String na
me = "李刚";
!!! 大家最好不要像上面这样写,一点用都没有。行行写好规范。
花括号的作用就是定义一个代码块,一个代码块指的就是" {“和”}"所包含的一段代码,代码块在逻辑上是一个整体,对Java 语言而言,类定义部分必须放在一个代码块里,方法体部分也必须放在个代码块里。除此之外,条件语句中的条件执行体和循环语句中的循环体通常也放在代码块里。
方括号的主要作用是用于访问数组元素 方括号通常紧跟数组变量名,而方括号里指定希望访问的数组元素的索引。
例如,如下代码:
// 下面代码试图为名为a的数组的第四个元素赋值
a[3]=3;
圆括号是一个功能非常丰富的分隔符:定义方法时必须使用圆括号来包含所有的形参声明,调用方法时也必须使用圆括号来传入实参值;不仅如此,圆括号还可以将表达式中某个部分括成一个整体,保证这个部分优先计算;除此之外,圆括号还可以作为强制类型转换的运算符。
Java 言使用空格分隔一条语句的不同部分。Java 语言是一门格式自由的语言,所以空格几乎可以出现在 Java 程序的任何地方 ,也可以出现任意多个空格,但不要使用空格把 个变量名隔开成两个,这将导致程序出错。
Java 语言中的空格包含空格符 (Space) 、制表符 (Tab) 和回车(Enter) 等。
圆点(.)通常用作类/对象和它的成员(包括成员变量、方法和内部类)之间的分隔符,表明调用某个类或某个实例的指定成员 。关于圆点分隔符的用法,后面还会有更进一步的介绍,此处不再赘述。
标识符就是用于给程序中变量、类、方法命名的符号。Java语言的标识符必须以字母、下画线( _ )、美元符( $ )开头,后面可以跟任意数目的字母、数字、下画线( _ )和美元符( $ )。此处的字母并不局限于26个英语字母,甚至可以包含中文字符、日文字符等。
由于 Java 9 支持 Unicode 8.0 字符集,因此 Java 的标识符可以使用 Unicode 8.0 所能表示的多种语字符。 Java语言是区分大小写的,因此abc 和Abc是两个不同的标识符。
Java 9 规定:不允许使用单独的下画线( _ ) 作为标识符。也就是说,下画线必须与其他字符组合在一起才能作为标识符。使用标识符,需要注意如下规则:
Java语言中有一些具有特殊用途的单词被称为关键字(keyword),当定义标识符时,不要让标识符和关键字相同。例如,下面代码会报错:
//试图定义一个名为boolen的变量,但boolen是关键字,不能作为标识符
int boolen;
Java的所有关键字都是小写,TURE,FALSE和NULL都不是Java关键字,Java共有50个关键字。
abstract | continue | for | new | switch |
---|---|---|---|---|
assert | default | if | package | synchronized |
boolean | do | goto | private | this |
break | double | implements | protected | throw |
byte | else | import | public | throws |
case | enum | instanceof | return | transient |
catch | extends | int | short | try |
char | final | interface | static | void |
class | finally | long | strictfp | volatile |
const | float | native | super | while |
上面的50个关键字,enum是从Java 5 新增的关键字,用于定义一个枚举。而goto和const这两个关键字也被称为保留字(reserved word),保留字的意思是,Java现在还未使用这两个关键字,可能在未来版本中会用到。不仅如此,Java还提供了三个特殊的直接量(literal):true、false和null。
Java 语言是强类型(strongly typed)语言,强类型包含两方面:1. 所有的变量必须先声明、后使用。 2. 指定类型的变量只能接受类型与之匹配的值。这意味着每个变量和每个表达式都有一个在编译时就确定的类型。类型限制了一个变量能被赋的值,限制了一个表达式可以产生的值,限制了在这些值上可以进行的操作,并确定了这些操作的含义。
!!! 哎,这些真的学过很多遍了,这里就少写一点吧,感觉也不会很想回来看。
Java语言支持的类型分成两类:基本类型(Primitive Type) 和 引用类型( Reference Type)。
基本类型包括boolean类型和数值类型。数值类型有整数类型和浮点类型。整数类型包括bytes、short、int、long、char,浮点类型包括float 和 double。
引用类型包括类、接口和数组类型,还有一种特殊得null类型,所谓引用数据类型就是对一个对象得引用,对象包括实例和数组两种。实际上,引用类型变量就是一个指针,只是Java语言没有指针这个说法。
整型一般包括下面4种类型:
int 是最常用的整数类型,因此在通常情况下,直接给出一个整数值默认就是 int 类型。除外,有如下两种情形必须指出:
//下面正确
byte a = 56;
/*
下面代码是错误的,系统不会把9999999999999当成long类型处理
所以超出int的表数范围,从而引起错误
*/
// long bigValue = 9999999999999
// 下面代码是正确的,在巨大的整数数值后使用L后缀,强制使用long类型
long bigValue2 = 92312323123242311L;
PS: 可以把一个较小的整数值(在 int 类型的表数范围以内)直接赋给一个 long 类型的变量,这并不是因为 Java 会把这个较小的整数值当成 long 类型来处理, Java 依然把这个整数值当成 int 类型来处理,只是因为 int 类型的值会自动类型转换到 long 类型。
Java中整数值有4种表达方式:十进制、二进制、八进制和十六进制,其中二进制的整数以0b 或 0B开头;八进制的整数以0开头;十六进制的整数以0x或者0X开头,其中10~15 分别以a ~ f 来表示。
//以0开头的整数值是八进制的整数
int octalValue = 013;
// 以0x或0X开头的整数值是十六进制的整数
int hexValue1 = 0x13;
int hexValue2 - 0XaF;
某些时候,程序需要直接使用二进制整数,二进制整数更“真实”,更能表达整数在内存中的存在形式。
//定义两个8位的二进制整数
int binVal1 = 0b11010100;
byte binVal2 = 0B01101001;
//定义一个32位的二进制整数,最高位是符号为
int binVal3 = 0B10000000000000000000000000000011;
System.out.println(binVall); //输出212
System.out.println(binVal2); //输出105
System.out.println(binVal3); //输出-2147483645
记住,当定义32位的二进制整数时,最高位其实是符号位,当符号位是1时,表明它是一个负数,负数在计算机里是以补码的形式存在的,因此还需要换算成原码。
所有数字在计算机底层都是以二进制形式存在的,原码是直接将一个数值换算成二进制数。但计算机以补码的形式保存所有的整数。补码的计算规则:正数的补码和原码完全相同,负数的补码是其反码加1;反码是对原码按位取反,只是最高位(符号位)保持不变。
/*
定义一个8位的二进制整数,该数值默认占32位,因此它是一个正数
只是强制类型转换成byte时产生了溢出,最终导致binVal4变成了-23
*/
byte binVal4 = (byte)0b11101001;
/*定义一个32位的二进制整数,最高位是1
但由于数值后添加了L后缀,因此该整数实际占64位,第32位的l不是符号位
因此binVal5的值等于2的31次方 +2 +1
*/
long binVal5 = 0B100000000000000000000000000000llL;
System. out . println(binVa14) ; //输出 23
System.out.println(binVa15 ); 11 输出 2147483651
上面程序中粗体字代码与前面程序片段的粗体字代码基本相同,只是在定义 进制整数时添加了"L" 后缀,这就表明把它当成 lon 类型处理,因此该整数实际占 64位,此时的第 32 位不再是符号位,因此它依然是一个正数。
至于程序中的 byte bin Val4 = (byte )0b1110100;代码,其中 0bl1101001 然是 32 位的正整数是程序进行强制类型转换时发生了溢出,导致它变成了负数。
Java语言使用16位的Unicode 字符集作为编码方式,而Unicode被设计成支持所有语言,所以中文当然也适合的呀。字符型值有如下三种表示形式:
由于计算机底层保存字符时,实际是保存该字符对应的编号,因此char类型的值也可以直接作为整型来使用,它相当于16位的无符号整数,表数范围是0~65535.
char类型的变量,值完全可以参与加、减、乘、除等数学运算,也可以比较大小——实际上都是用该字符对应的编码参与运算。
public class CharTest
{
public static void main(String[] args)
{
//直接指定单个字符作为字符值
char aChar = 'a';
//使用转义字符来作为字符值
char enterChar = '\r';
//使用Unicode编码值来指定字符值
char ch = '\u9999';
//将输出一个‘香’字符
System.out.println(ch);
//定义一个‘疯’字符值
char zhong = '疯';
//直接将一个char变量当成int类型变量使用
int zhongValue = zhong
System.out.println(zhongValue);
//直接把一个0~65535范围内的int整数赋给一个char变量
char c = 97;
System.out.println(c);
}
}
注意:
char 类型使用单引号括起来,而字符串使用双引号括起来,关于 String 类的用法以及对应的各种方法,读者应该通过查 API 文档来掌握,以 来练习使用 API 文档。
值得指出的是, Java 语言中的单引号、双引号和反斜线都有特殊的用途 ,如果一个字符串中包含了这些特殊字符,则应该使用转义字符的表示形式 例如,在 Java 程序中表示 个绝对路径 :曰 :\codes" ,但这种写法得不到期望的结果 因为 Java 会把反斜线当成转义字符,所以应该写成这种形式 “c:\codes” , 只有同时写两个反斜线, Java 会把第一个反斜线当成转义字符,和后 个反斜线组成真正的反斜线。
Java的浮点类型有两种:float喝double。Java的浮点类型有固定的表数范围和字段长度。Java的浮点数遵循 IEEE 754标准,采用二进制数据的科学记数法来表示浮点数,对于float类型,第1位是符号位,接下来8位表示指数,在接下来的23位表示尾数;对于double类数值,第1位也是符号位,接下来的11位表示指数,再接下来的52位表示尾数。
double类型代表双精度浮点数,float类型代表单精度浮点数。一个double类型的数值占8字节、64位,一个float类型的数值占4字节、32位。Java语言的浮点数有两种表示形式:
Java 语言的浮点类型默认是 double 类型,如果希望 Java 个浮点类型值当成 float 类型处理,应该在这个浮点类型值后紧跟f或F。5.12 代表一个 doubl 类型的值,占64位的内存空间 5.12f 或者 5.12F 才表示一个 float 类型的值,占32位的内存空间。
Java 还提供了 个特殊的浮点数值:正无穷大、负无穷大和非数,用于表示溢出和出错。正无穷大通过 Double或 Float 类的 POSITIVE_INFINITY 表示:负无穷大通过Double 或Float 类的NEGATIVE_INFINITY 表示,非数通过 Double或Float 类的 NaN 表示。所有的正无穷大数值都是相等的,所有的负无穷大数值都是相等的;而NaN不与任何数值相等,甚至和NaN都不相等。
只有浮点数除以0才可以得到正无穷大或负无穷大,因为 Java 语言会自动把和浮点数运算的0(整数)当成 0.0(浮点数)处理。如果 个整数值除以 ,则会抛 出一个异常 :ArithmeticException: / by zero(除以 异常)
public class FloatTest
{
public static void main(String[] args)
{
float af = 5.2345556f;
//下面将看到af的值已经发生了改变
System.out.println(af);
double a = 0.0;
double c = Double.NEGATIVE_INFINITY;
float d = Float.NEGATIVE_INFINITY;
//看到float和double的负无穷大是相等的
System.out.println(c==d);
//0.0 除 0.0 将出现非数
System.out.println(a /a);
//两个非数之间是不相等的
System.out.println(a/a == Float.NaN);
//所有无穷大都是相等的
System.out.println(6.0/ 0 == 555.0/0);
//负数除以0.0 得到负无穷大
System.out.println( -8/a);
//下面代码会抛出异常
//System.out.println(0/0)
}
}
为了很好的计算数字的位数,可以使用下画线来进行对数字的分割。
public class UnderscoreTest
{
public static void main(String[] args)
{
//定义一个32位的二进制数,最高位是符号位
int binVal = 0B1000_0000_0000_0000_0000_0000_0000_0011;
double pi = 3.14_15_92_65_36;
System.out.println(binVal);
System.out.println(pi);
double height = 8_8_4_8.23;
System.out.println(height);
}
}
布尔型只有 boolean 类型,用于表示逻辑上的"真"或"假"。在 Java 语言中, boolean 类型的数值只能是 true 和 false ,不能用 0或者非0来代表。其他基本数据类型的值也不能转换成 boolean 类型。
Java语言所提到的7中之间可以互相转换,有两种转换方式:自动类型转换和强制类型转换。
Java 所有的数值型变量可以相互转换,如果系统支持把某种基本类型的值直接赋给另一种基本类型的变 ,则这种方式被称为自动类型转换,当把一个表数范围小的数值或变量直接赋给另 个表数范围大的变时,系统将可以进行自动类型转换;否则就需要强制转换。
如图所示,视频中箭头指的数据类型都可以自行进行转换。
public class AutoConversion
{
public static void main(String[] args)
{
int a = 6;
//int 类型可以自动转换为float类型
float f = a;
//下面将输出6.0
System.out.println(f);
//定义一个byte类型的整数变量
byte b = 9;
//下面代码会出错,byte类型不能自动转换为char类型
//char c = b;
// byte类型可以自动转换为double类型
double d = b;
//输出9
System.out.println(d);
}
}
不仅如此,当把任何基本类型的值和字符串进行连接运算时,基本类型的值将自动转换为字符串类型,虽然字符串类型不是基本类型,而是引用类型。因此,如果希望把基本类型转换为对应的字符串时,可以把基本类型的值和一个空字符串进行连接。
public class PrimitiveAndString
{
public static void main(String[] args)
{
//下面代码是错误的,因为S是一个整数,不能直接赋值给一个字符串
//String str1 = 5;
//一个基本类型的值和字符串进行连接运算时,基本类型的值自动转换为字符串
String str2 = 3.5f + "";
//下面输出3.5
System.out.println(str2);
//下面语句输出7hello
System.out.println(3+4+"hello!");
//下面语句输出Hello!34,因为ihello!+3会把3当作字符串,再把4当作字符串
System.out.println("Hello!"+3+4);
}
}
感觉其实就是从左到右进行格式转换,并没有什么要讲的。
上面的图,如果希望将箭头右边的类型转换为左边的类型,则必须进行强制类型转换。如果数据过大,会造成数据溢出。
public class NarrowConversion
{
public static void main(String[] args)
{
int iValue = 233;
//强制把一个int类型的值转换为byte类型的值
byte bValue = (byte)iValue;
//将输出-23
System.out.println(bValue);
double dValue = 3.98;
//强制把一个double类型的值转换为int类型的值
int tol = (int)dValue;
//将输出3
System.out.println(tol);
}
}
32 位int 类型的 233 在内存中如图 上面所示,强制类型转换为 位的 byte类型,则需要截断前面的24位,只保留右边8位,最左边1的一个符号位,此处表明这是一个负数,负数在计算机里是以补码形式存在的,因 还需要换算成原码将补码减1,得到反码形式,再将反码取反就可以得到原码。
&esmp; 经常上网的读者可能会发现有些网页上会包含临时生成的验证字符串,那么这个随机字符串是如何生成的呢?可以先随机生成一个在指定范围内的int数字,然后强制转换为char类型。
public class RandomStr
{
public static void main(String[] args)
{
//定义一个空字符串
String result = "";
//进行6次循环
for(int i = 0; i<6;i++)
{
//生成一个97~122之间的int整数
int intVal = (int)(Math.random()*26+97);
//将intValue强制转换为char后加到result后面
result = result + (char)intVal;
}
//输出
System.out.println(result);
}
}
下面这行代码容易报错:
//直接把5.6赋值给float类型变量将出现错误,因为5.6默认是double类型
float a = 5.6;
//因此将 5.6 赋值给 float 类型变量将导致错误,必须使用强制类型转换才可以
float a = (float)5.6;
把字符串转换为int类型:
String a = "45"
int iValue = Integer.parseInt(a);
Java为8种基本类型都提供了对应的包装类:boolean对应Boolean、byte对应Byte、short对应Short、int对应Integer、long对应Long、char对应Character、float对应Float、double对应Double。8个包都有parseXxx(String str)将字符型转换为基本类型。
当一个算术表达式中包含多个基本类型的值时,整个算术表达式的数据类型将发生自动提升。Java定义了如下的自动提升规则。
//定义一个short类型
short sValue = 5;
//表达式中的sValue将自动提升到int类型,则右边的表达式类型为int
//将一个int类型值赋给short类型变量将发生错误
sValue = sValue - 2;
为什么会报错呢?sValue -2 会变成整型变量,然后赋值到short类型会报错。
byte b = 40;
char c = 'a';
int i = 23;
double d = .314;
//右边表达式中最高等级操作数为d
//则右边表达式的类型为double类型,故赋给double类型变量
double result = b+c +i *d;
//输出 144.222
System.out.println(result);
必须指出,表达式的类型将严格保持和表达式中最高等级操作数相同的类型。下面代码中两个int 类型整数进行除法运算,即使无法除尽, 也将得到 int 类型结果。
int val = 3 ;
// 右边表达式中两个操作数都是工 nt 类型,故右边表达式的类型为 int
// 虽然 23 不能除尽,但依然得到 in 类型整数
int intResult = 23 / val ;
System.out.println(intResult); // 将输出 7
直接量是指在程序中通过源代码直接给出的值。例如int a = 5。Java支持8种类型的直接量:
感觉就是直接赋值,没什么好讲的。
Java 语言中的运算符可分为如下几种:
基本运算符:加(+)、减(-)、乘(*)、除(/)和求余(%),自加(++)。这个简单不写了
Java支持的位运算符有如下7个:
//会转换成二进制再取运算
System.out.println(5 & 9); //输出1
//5为0000101, 9为00001001,与运算得000001
负数的话,要先转换成补码,在进行位运算。比如-5的话,需要先除符号位取反得到反码,再加1得到补码,进行运算。
注意:
进行移位运算时还要遵循如下规则:
逻辑运算符用于操作两个布尔型的变量或常量 逻辑运算符主要有如下6个:
至于 || 和 |,以及 && 和 & 的区别:对于短路与&&,会先执行左边的运算,如果返回true,则不会运算右边,而 | 两边都会进行运算。&&一样
三目运算符只有一个: ?:
(experssion) ? if-true-satement : if-else-statement;
三目运算符的规则是 先对逻辑表达式 expresslO 求值,如果逻辑表达式返回 true ,则返回第二操作数的值,如果逻辑表达式返回 fa se ,则返回第三个操作数的值。我记得python是有这个运算的。
所有的数学运算都认为是从左向右运算的, Java 语言中大部分运算符也是从左向右结合的,只有单目运算符、赋值运算符和 目运算符例外,其中,单目运算符、赋值运算符和三目运算符是从右向左结合的 ,也就是从右向左运算。