一、基本数据类型
Java中,变量的目的是申请内存来存储值。也就是说,当一个变量被创建时,就需要在内存中申请空间,内存管理系统根据变量的类型为变量分配相应的存储空间,此时分配的空间只能用来存储该类型数据。
Java有两大数据类型:
1>内置数据类型
2>引用数据类型
Java中,共有八种基本类型:六种数字类型(四整型,二浮点型),一种字符类型,一种布尔类型。
1.1 整型数据
整形数据分为4种:
1>byte
8位,有符号整数,范围为-27 ~ 27-1,默认值是0。
2>short
16位,有符号整数,范围为-215 ~ 215-1,默认值是0。
3>int
32位,有符号整数,范围为-231~ 231-1,默认值为0,一般整型变量默认为int型。
4>long
64位,有符号整数,范围为-263 ~ 263-1,默认值为0L。赋予long型变量初始值时,需要在数字后面加上L。
测试代码如下:
static byte b1;
static short s1;
static int i1;
static long l1;
public static void main(String[] args){
System.out.println("byte型变量默认值 :"+b1 );
System.out.println("short型变量默认值 :"+s1 );
System.out.println("int型变量默认值 :"+i1 );
System.out.println("long型变量默认值 :"+l1 );
}
测试结果:
byte型变量默认值 :0
short型变量默认值 :0
int型变量默认值 :0
long型变量默认值 :0
1.2 浮点型数据
整形数据分为2种:
1>float
单精度,32位,默认值是0.0f。
2>double
双精度,64位,默认值是0.0d,浮点型变量默认为double型。
测试代码如下:
static float f1;
static double d1;
public static void main(String[] args){
System.out.println("float型变量默认值 :"+f1 );
System.out.println("double型变量默认值 :"+d1 );
}
测试结果:
float型变量默认值 :0.0
double型变量默认值 :0.0
1.3 布尔型数据
boolean,1位,只有两个取值:true和false,默认值是false。
测试代码如下:
static boolean b1;
public static void main(String[] args){
System.out.println("boolean型变量默认值 :"+b1 );
}
测试结果:
boolean型变量默认值 :false
1.4 字符型数据
char,16位Unicode字符,范围为0 ~ 215-1(\u0000到\uffff),可存储任意字符,默认值是’u0000’。
每种数据类型的取值范围可以通过其包装类来查看,如下:
类型 | 位数 | 最大值 | 最小值 |
---|---|---|---|
byte | Byte.SIZE | Byte.MAX_VALUE | Byte.MIN_VALUE |
short | Short.SIZE | Short.MAX_VALUE | Short.MIN_VALUE |
int | Integer.SIZE | Integer.MAX_VALUE | Integer.MIN_VALUE |
long | Long.SIZE | Long.MAX_VALUE | Long.MIN_VALUE |
float | Float.SIZE | Float.MAX_VALUE | Float.MIN_VALUE |
double | Double.SIZE | Double.MAX_VALUE | Double.MIN_VALUE |
char | Character.SIZE | Character.MAX_VALUE | Character.MIN_VALUE |
测试代码如下:
System.out.println("byte型变量位数:"+Byte.SIZE+",byte型变量最大值:"+Byte.MAX_VALUE+",byte型变量最小值:"+Byte.MIN_VALUE );
System.out.println("short型变量位数:"+Short.SIZE+",short型变量最大值:"+Short.MAX_VALUE+",short型变量最小值:"+Short.MIN_VALUE );
System.out.println("int型变量位数:"+Integer.SIZE+",int型变量最大值:"+Integer.MAX_VALUE+",int型变量最小值:"+Integer.MIN_VALUE );
System.out.println("long型变量位数:"+Long.SIZE+",long型变量最大值:"+Long.MAX_VALUE+",long型变量最小值:"+Long.MIN_VALUE );
System.out.println("float型变量位数:"+Float.SIZE+",float型变量最大值:"+Float.MAX_VALUE+",float型变量最小值:"+Float.MIN_VALUE );
System.out.println("double型变量位数:"+Double.SIZE+",double型变量最大值:"+Double.MAX_VALUE+",double型变量最小值:"+Double.MIN_VALUE );
System.out.println("char型变量位数:"+Character.SIZE+",char型变量最大值:"+Character.MAX_VALUE+",char型变量最小值:"+Character.MIN_VALUE );
测试结果:
byte型变量位数:8,byte型变量最大值:127,byte型变量最小值:-128
short型变量位数:16,short型变量最大值:32767,short型变量最小值:-32768
int型变量位数:32,int型变量最大值:2147483647,int型变量最小值:-2147483648
long型变量位数:64,long型变量最大值:9223372036854775807,long型变量最小值:-9223372036854775808
float型变量位数:32,float型变量最大值:3.4028235E38,float型变量最小值:1.4E-45
double型变量位数:64,double型变量最大值:1.7976931348623157E308,double型变量最小值:4.9E-324
char型变量位数:16,char型变量最大值:,char型变量最小值:
包装类还可以用来实现基本数据类型之间的转换,每个包装类中总有xxValue方法,来获得其对应的简单数据类型。
String不是Java的基本数据类型,默认值为null。
其他数据类型转换为String的方式:
1>X.toString()
2>X+""
3>String.valueOf(X)
此处以int型数据转换为String为例,测试代码如下:
Integer i1 = 1;
String str1 = i1.toString();
String str2 = i1+"";
String str3 = String.valueOf(i1);
System.out.println(str1+","+str2+","+str3);
测试结果:
1,1,1
String数据转换为其他简单类型的方式:
1>包装类的xxValue(),比如:Double.valueOf(“32.1”).doubleValue()。
2>包装类的静态parseXX方法,比如:Double d = Double.parseDouble(s)。
Java中,任何类型与字符串相加,都是进行拼接。原理为:先用String.valueOf()方法,再通过StringBuilder进行拼接。
此处以int型数据转换为String为例,测试代码如下:
String str1 = "123";
int i1 = Integer.valueOf(str1).intValue();
int i2 = Integer.parseInt(str1);
System.out.println(i1+","+i2);
测试结果:
123,123
Java中,引用类型的变量类似于C/C++中的指针,引用类型指向一个对象,指向对象的变量是引用变量。引用变量在声明时被指定为一个特定类型,并且不允许更改。
对象、数组是引用数据类型,引用类型的默认值是null。
final修饰常量,为了便于识别,一般用大写字母表示。
Java常用转义字符:
符号 | \n | \r | \f | \b | \0 | \s | \t | " | ’ | \ |
---|---|---|---|---|---|---|---|---|---|---|
意义 | 换行 | 回车 | 换页 | 退格 | 空字符 | 字符串 | 制表符 | 双引号 | 单引号 | 反斜杠 |
Java中,整型、常量、字符型数据可以混合运算。不同类型的数据进行运算时,会先转换为同一类型(更高的数据类型),再进行运算。
各变量优先级如下:
低 ----------------------------------------------------> 高
byte,short,char—> int —> long—> float —> double
数据类型转换时需要注意的规则:
1>不能对boolean类型进行类型转换。
2>把优先级高的转换为优先级低时必须使用强制类型转换
3>转换过程中可能导致溢出或损失精度
自动类型转换发生在转换前的数据类型的位数低于转换后的数据类型。
强制类型转换发生的条件是转换前后的数据类型必须是兼容的。
强制类型转换的格式为:(type)value。
二、变量类型
Java中的变量类型大致可分为3种:
1>类变量,方法体之外的变量,用 static 修饰。
2>实例变量,方法体之外的变量,无 static 修饰。
3>局部变量:方法体中的变量。
2.1 局部变量
局部变量的特征:
1>声明在方法、构造方法或者语句块中。
2>在方法、构造方法、或者语句块被执行的时候创建,执行完后,变量将会被销毁。
3>只在声明它的方法、构造方法或者语句块中可见,访问修饰符不能用于局部变量。
4>所占用的内存空间在栈。
5>没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用。
2.2 实例变量
实例变量的特征:
1> 声明在一个类中,但在方法、构造方法和语句块之外。
2>当一个对象被实例化之后,每个实例变量的值就跟着确定。
3>实例变量在对象创建的时候创建,在对象被销毁的时候销毁。
4>访问修饰符可以修饰实例变量。
5>实例变量对于类中的方法、构造方法或者语句块是可见的。
6>实例变量具有默认值。数值型变量的默认值是0,布尔型变量的默认值是false,引用类型变量的默认值是null。
7>实例变量可以直接通过变量名访问。
2.3 类变量/静态变量
静态变量的特征:
1>在方法体之外,用static关键字声明。
2>静态变量的数量与该类创建的对象数量无关,只有一个。
3>静态变量储存在静态存储区。
4>静态变量在第一次被访问时创建,在程序结束时销毁。
5>默认值和实例变量相似。数值型变量默认值是0,布尔型默认值是false,引用类型默认值是null。变量的值 6>可以在声明的时候指定,也可以在构造方法中指定。此外,静态变量还可以在静态语句块中初始化。
类变量被声明为public static final类型时,类变量名称一般建议使用大写字母,此时的作用就是与常量相同。
静态变量与实例变量的区别:
1>静态变量属于类,该类不生产对象,通过类名就可以调用静态变量。
2>实例变量属于该类的对象,必须产生该类对象,才能调用实例变量。
三、修饰符
Java中修饰符主要分为:访问修饰符和非访问修饰符。
3.1 访问修饰符
顾名思义,该类修饰符重要控制访问权限。不同修饰符的修饰对象,大致如下:
1>default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
2>private : 在同一类内可见。使用对象:变量、方法。
3>protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。
4>public : 对所有类可见。使用对象:类、接口、变量、方法。
不同修饰符的访问范围,如下:
修饰符 | 当前类 | 同包类 | 子类 | 其他类 |
---|---|---|---|---|
public | Y | Y | Y | Y |
protected | Y | Y | Y | N |
default | Y | Y | N | N |
private | Y | N | N | N |
接口里的变量都隐式声明为 public static final,而接口里的方法默认情况下访问权限为 public。
声明为 private 的方法、变量和构造方法只能被所属类访问,并且类和接口不能声明为 private。也就是说,声明为private的方法和变量,都是当前类内部使用的,外部不能访问。
protected特征:
1>子类与基类在同一包中,被声明为 protected 的变量、方法和构造器能被同一个包中的任何其他类访问。
2>子类与基类不在同一包中,那么在子类中,子类实例可以访问其从基类继承而来的 protected 方法,而不能访问基类实例的protected方法。
访问控制和继承规则:
1>父类中声明为 public 的方法在子类中也必须为 public。
2>父类中声明为 protected 的方法在子类中要么声明为 protected,要么声明为 public,不能声明为 private。
3>父类中声明为 private 的方法,不能够被继承。
这三条规则体现的访问权限放大机制,即子类方法的方法访问权限>=父类的方法访问权限。
3.2 非访问修饰符
非访问修饰符,主要有static、final、abstract。
1>static
static修饰变量,就是静态变量,一个类只有一个静态变量。
static修饰方法,通过类名而不是该类实例化的对象调用。
2>final
final修饰变量,声明的时候必须初始化,不能被修改。
final修饰方法,可以被子类继承,但是不能被子类重写。
final修饰类,不能被继承。
3>abstract
abstract修饰类,不能被实例化。
abstract修饰方法,需要被子类重写,除非子类也是抽象类。
四、表达式
Java表达式是变量、常量、运算符、方法调用的序列,执行指定的计算并返回特定的值。
表达式一般是按运算符来划分的,表达式种类如下:
1>算术表达式
2>关系表达式
3>布尔逻辑表达式
4>位运算表达式
5>赋值表达式
6>条件表达式
4.1 算术运算符
+ - * / % ++ –
a++代表先使用,再+1,;–a代表先减1,再使用。测试代码如下:
for(int i=0;i<3;i++){
System.out.println(i);
}
测试结果:
0
1
2
由这个例子可以看出,i++这种自增或自减符号在运算表达式或变量后面的,是先使用,再变化。
4.2 关系运算符
== != > < >= <=
关系运算符比较的都是值,而非引用。
4.3 位运算
位运算应用于char、short、int、long型数据。
位运算方式:
1>&,都为1,结果则为1,否则为0。
2>|,都为0,结果为0,否则为1。
3>^,相同为0,不同为1。
4>~,取反。
5> <<,按位左移运算符,乘2的n次方。
6> >>,按位右移运算符,除2的n次方。
4.4 逻辑运算符
逻辑运算有三种:
1>&&,逻辑与运算,都为真结果则为真。
2>||,逻辑或运算符,有真则为真。
3>!,逻辑非运算符,取反。
&&为短路逻辑与运算符,即前面的判断条件为false时,不再进行后面条件的判断。
关于短路功能,测试代码如下:
int i=1;
if(i==2 && (i++)==2)
System.out.println("test");
System.out.println("i:"+i);
测试结果:
i:1
由这个例子可以看出:当&&前面的判断条件i==2不成立时,后面的判断语句也没有进行。
4.5 赋值运算符
= += -= *= /= %= <<= >>= &= ^= |=
特殊赋值运算符(如:+=)可以在不改变原有数据类型的情况下实现运算,如果两个值数据类型不一致,会进行强制数据类型转换。测试代码如下:
int i=1;
i+=2;
System.out.println("i:"+i);
i+=2.0f;
System.out.println("i:"+i);
测试结果:
i:3
i:5
4.6 条件运算符
即三元运算符,形式为:x = (expression) ? trueVal : falseVal。测试代码如下:
int gradeA=98;
int gradeB=93;
int betterGrade=0;
betterGrade=gradeA>gradeB?gradeA:gradeB;
System.out.println("两个同学中较好的成绩是:"+betterGrade);
测试结果:
两个同学中较好的成绩是:98
4.7 instanceof运算符
判断一个对象是否是一种类型,形式为:val instanceof Type(Type是自身类或父类均可)。
Java运算符优先级(从上往下依次递减):
类别 | 操作符 | 运算顺序 |
---|---|---|
后缀 | () [] . (点操作符) | 左到右 |
一元 | + + – (此处指的是先执行自增或自减,再执行表达式) | 左到右 |
一元 | + + – (此处指的是先执行表达式,再执行自增或自减) ! 〜 | 右到左 |
乘性 | * /% | 左到右 |
加性 | + - | 左到右 |
移位 | >> >>> << | 左到右 |
关系 | > > = < < = | 左到右 |
相等 | == != | 左到右 |
按位与、异或、或 | &、^、 | |
逻辑与、或 | &&、 | |
条件 | ?: | 左到右 |
赋值 | = + = - = * = / =%= >> = << =&= ^ = | = |
五、数组
一个数组就代表在内存中开辟一段连续、用来存储相同类型数据的空间,其特征如下:
1>数组名代表的是连续空间的首地址。
2>通过首地址可以依次访问数组所有元素,元素在数组中的位置叫做下标,从零开始。
3>数组长度一旦声明,不可改变不可追加。
5.1 声明数组
数组的声明方式有两种,以int型数组举例:int[ ] array和int array[ ]。
5.2 创建数组
数组的创建方式也有两种,以int型数组举例。
1>int[ ] array = new int[10]
该语句的意思是创建一个容量大小为10的int型数组,数组中默认值是0(即int型变量的默认值)。
2>int[ ] array={1,2,3,4,5,6}
该语句的意思是创建一个容量大小为6的int型数组,数组中的初始值为1,2,3,4,5,6。
5.3 遍历数组
数组的遍历方式也有两种,以int型数组举例。
1>for循环
这是最常用的遍历方式,示例如下:
for(int i=0;i<array.length;i++)
System.out.println(array[i]+" ");
2>foreach循环
示例如下:
for(int arr:array)
System.out.println(arr+" ");
5.4 Arrays类
Arrays是一个封装好一些对数组操作的类,其中的public方法都是静态的,主要有以下几大类:
1>搜索类
该类方法的作用是在数组中搜索某个值,返回该值在数组中的下标。该类方法的实现是二分搜索,例如在int数组中搜索某个值,方法具体代码如下:
public static int binarySearch(int[] array, int startIndex, int endIndex, int value) {
checkBinarySearchBounds(startIndex, endIndex, array.length);
int lo = startIndex;
int hi = endIndex - 1;
while (lo <= hi) {
int mid = (lo + hi) >>> 1;
int midVal = array[mid];
if (midVal < value) {
lo = mid + 1;
} else if (midVal > value) {
hi = mid - 1;
} else {
return mid; // value found
}
}
return ~lo; // value not present
}
2>赋值类
该类方法的作用是给数组中元素赋予默认值,实现是遍历赋值。示例代码如下:
public static void fill(int[] array, int start, int end, int value) {
Arrays.checkStartAndEnd(array.length, start, end);
for (int i = start; i < end; i++) {
array[i] = value;
}
}
3>计算哈希值类
该类方法的作用是计算数组中元素的哈希值。示例代码如下:
public static int hashCode(int[] array) {
if (array == null) {
return 0;
}
int hashCode = 1;
for (int element : array) {
// the hash code value for integer value is integer value itself
hashCode = 31 * hashCode + element;
}
return hashCode;
}
4>比较值类
该类方法的作用是比较两个数组是否相等。示例代码如下:
public static boolean equals(int[] array1, int[] array2) {
if (array1 == array2) {
return true;
}
if (array1 == null || array2 == null || array1.length != array2.length) {
return false;
}
for (int i = 0; i < array1.length; i++) {
if (array1[i] != array2[i]) {
return false;
}
}
return true;
}
5>排序类
该类方法的作用是对数组中的元素进行排序,用到的排序方式是快速排序。示例代码如下:
public static void sort(int[] array, int start, int end) {
DualPivotQuicksort.sort(array, start, end);
}
6>转换为字符串类
该类方法的作用是将数组中的元素转换为String。示例代码如下:
public static String toString(int[] array) {
if (array == null) {
return "null";
}
if (array.length == 0) {
return "[]";
}
StringBuilder sb = new StringBuilder(array.length * 6);
sb.append('[');
sb.append(array[0]);
for (int i = 1; i < array.length; i++) {
sb.append(", ");
sb.append(array[i]);
}
sb.append(']');
return sb.toString();
}
7>拷贝类
该类方法的作用是拷贝数组中的元素,可以指定起始位置,未指定初始位置的话,默认从0开始。示例代码如下:
public static int[] copyOf(int[] original, int newLength) {
if (newLength < 0) {
throw new NegativeArraySizeException(Integer.toString(newLength));
}
return copyOfRange(original, 0, newLength);
}
六、Math类
Math类包含用于执行基本数学运算的方法。常用方法有:三角函数类方法和数值计算类方法。
6.1 三角函数类方法
1>public static native double acos(double d)
double类型参数的反余弦值。
2>public static native double asin(double d)
double类型参数的反正弦值,范围在 -pi/2 到 pi/2 之间。
3>public static native double atan(double d)
double类型参数的反正切值,范围在 -pi/2 到 pi/2 之间。
4>public static native double cos(double d)
double类型参数的余弦值。
5>public static native double sin(double d)
double类型参数的三角正弦值。
6>public static native double tan(double d)
double类型参数的三角正切值。
6.2 数值计算类方法
1>public static double abs(double d)
double型变量的绝对值。
2>public static double abs(double d)
float型变量的绝对值。
3>public static int abs(int i)
int型变量的绝对值。
4>public static long abs(long l)
long型变量的绝对值。
5>public static native double ceil(double d)
对一个数进行上舍入,返回值大于或等于给定的参数,类型为双精度浮点型。测试代码如下:
double d = 10.6;
float f = -95;
System.out.println(Math.ceil(d));
System.out.println(Math.ceil(f));
结果为:
11.0
-95.0
6>public static native double floor(double d)
对一个数进行下舍入,返回给定参数最大的整数,该整数小于或等给定的参数。测试代码如下:
double d = 10.6;
float f = -95;
System.out.println(Math.floor(d));
System.out.println(Math.floor(f));
结果为:
10.0
-95.0
7>public static native double log(double d)
返回参数的自然数底数的对数值。测试代码如下:
System.out.printf("log(%.3f) 为 %.3f%n", Math.E*Math.E,Math.log(Math.E*Math.E));
结果为:
log(7.389) 为 2.000
8>public static native double log10(double d)
返回 double 值的底数为 10 的对数。测试代码如下:
System.out.printf("log(%.3f) 为 %.3f%n", 100.0,Math.log10(100.0));
结果为:
log(100.000) 为 2.000
8>public static double max(double d1, double d2)
返回两个 double 值中较大的一个。实现代码如下:
public static double max(double d1, double d2) {
if (d1 > d2) {
return d1;
}
if (d1 < d2) {
return d2;
}
/* if either arg is NaN, return NaN */
if (d1 != d2) {
return Double.NaN;
}
/* max(+0.0,-0.0) == +0.0 */
/* Double.doubleToRawLongBits(0.0d) == 0 */
if (Double.doubleToRawLongBits(d1) != 0) {
return d2;
}
return 0.0d;
}
10>public static float max(float f1, float f2)
返回两个 float值中较大的一个。实现代码如下:
public static float max(float f1, float f2) {
if (f1 > f2) {
return f1;
}
if (f1 < f2) {
return f2;
}
/* if either arg is NaN, return NaN */
if (f1 != f2) {
return Float.NaN;
}
/* max(+0.0,-0.0) == +0.0 */
/* Float.floatToRawIntBits(0.0f) == 0*/
if (Float.floatToRawIntBits(f1) != 0) {
return f2;
}
return 0.0f;
}
11>public static int max(int i1, int i2)
返回两个 int 值中较大的一个。实现代码如下:
public static int max(int i1, int i2) {
return i1 > i2 ? i1 : i2;
}
12>public static long max(long l1, long l2)
返回两个long值中较大的一个。实现代码如下:
public static long max(long l1, long l2) {
return l1 > l2 ? l1 : l2;
}
13>public static double min(double d1, double d2)
返回两个 double 值中较小的一个。实现代码如下:
public static double min(double d1, double d2) {
if (d1 > d2) {
return d2;
}
if (d1 < d2) {
return d1;
}
/* if either arg is NaN, return NaN */
if (d1 != d2) {
return Double.NaN;
}
/* min(+0.0,-0.0) == -0.0 */
/* 0x8000000000000000L == Double.doubleToRawLongBits(-0.0d) */
if (Double.doubleToRawLongBits(d1) == 0x8000000000000000L) {
return -0.0d;
}
return d2;
}
14>public static float min(float f1, float f2)
返回两个 float值中较小的一个。实现代码如下:
public static float min(float f1, float f2) {
if (f1 > f2) {
return f2;
}
if (f1 < f2) {
return f1;
}
/* if either arg is NaN, return NaN */
if (f1 != f2) {
return Float.NaN;
}
/* min(+0.0,-0.0) == -0.0 */
/* 0x80000000 == Float.floatToRawIntBits(-0.0f) */
if (Float.floatToRawIntBits(f1) == 0x80000000) {
return -0.0f;
}
return f2;
}
15>public static int min(int i1, int i2)
返回两个 int 值中较小的一个。实现代码如下:
public static int min(int i1, int i2) {
return i1 < i2 ? i1 : i2;
}
16>public static long min(long l1, long l2)
返回两个 long 值中较小的一个。实现代码如下:
public static long min(long l1, long l2) {
return l1 < l2 ? l1 : l2;
}
17>public static native double pow(double x, double y)
返回第一个参数的第二个参数次幂的值。测试代码如下:
double d1 = 10.0;
double d2 = 2.0;
System.out.println(Math.pow(d1,d2));
结果为:
100.0
18>public static synchronized double random()
返回一个随机数,随机数范围为 0.0 =< Math.random < 1.0。
19>public static long round(double d) / static int round(float f)
“四舍五入”,算法为Math.floor(x+0.5) ,即将原来的数字加上 0.5 后再向下取整。实现代码如下:
public static long round(double d) {
// check for NaN
if (d != d) {
return 0L;
}
return (long) floor(d + 0.5d);
}
public static int round(float f) {
// check for NaN
if (f != f) {
return 0;
}
return (int) floor(f + 0.5f);
}
测试代码如下:
System.out.println(Math.round(11.5));
System.out.println(Math.round(-11.5));
结果为:
12
-11
20>public static native double sqrt(double d)
返回正确舍入的 double 值的正平方根。
七、分支循环
Java中,除了普通的顺序结构外,特殊的结构有三种:
7.1 分支结构
if、if-else、if-else if-else结构适合多种情况下的语句执行。
switch-case结构与多种if结构作用相似,但是有局限性,其特点如下:
1>JDK1.7之前的版本中,switch语句支持的数据类型有byte、short、int、char和枚举类型;在JDK1.7及以后的版本中,增加了对String类型的支持。
2>break是每种case的结束标志,如无break则会继续走下个case。
3>一般最后都会有个default,用来处理匹配不到任何case的情况。
switch使用的测试代码如下:
int grade=80;
switch(grade){
case 60:
case 70:
System.out.println("你的成绩为60或70分");
break;
case 80:
System.out.println("你的成绩为80分");
break;
default:
System.out.println("你的成绩为60、70、80之外的分数");
break;
}
7.2 循环结构
Java中循环结构有两种:
1>for循环,有三部分:初始化操作、判断终止条件表达式及迭代部分。for循环一般用于循环次数已知的情况。
2>while循环,有两种:
while(判断条件){
循环体
}
do{
循环体
}while(判断语句);
do-while先执行循环体语句,然后进行判断,也就是无论如何会先执行一次循环体语句。
7.3 跳转语句
跳转语句有三种:break、continue、return。此外,异常处理也可以改变程序执行流程。
break有以下作用:
1>在switch中,用来终止一个语句序列。
2>用来退出一个循环。
continue只能用来for、while、do while循环中,用于跳过当前循环,直接进行下一次循环。
return语句使程序控制返回到调用它的地方。
八、关键字
Java关键字的标准定义是电脑语言里事先定义的,有特别意义的标识符,有时又叫保留字,还有特别意义的变量。Java的关键字对Java的编译器有特殊的意义,他们用来表示一种数据类型,或者表示程序的结构等,关键字不能用作变量名、方法名、类名、包名和参数。
8.1 所有关键字
java关键字共53个,包含两个保留字const,goto,具体如下:
关键字 | 意义 |
---|---|
abstract | 抽象 |
assert | 断言assert是jdk1.4引入的;jvm断言默认是关闭的;断言只适用复杂的调式过程;断言一般用于程序执行结构的判断,千万不要让断言处理业务流程 |
boolean | 布尔类型,值为true或false |
break | 结束一个语句块的执行,常用于switch…case和循环语句中 |
byte | 字节类型 |
case | 用于switch…case语句中,表示其中一个分支 |
catch | 用于try…catch语句中,用来捕捉异常 |
char | 字符类型 |
class | 类 |
const | 保留关键字 |
continue | 结束本次循环,进行下一次循环,主要用于for、while循环中 |
default | 用于switch…case语句中,表示匹配不上任何case的情况 |
do | 用于do…while循环中,其后是要默认执行一次的语句库 |
double | 双精度浮点类型 |
else | 表示条件不成立的情况 |
enum | 枚举 |
extends | 继承,用于类和类、接口和接口之间 |
final | 不可修改 |
finally | 用于try…catch语句中,用来处理不论是否捕捉到异常,都执行的语句 |
float | 单精度浮点类型 |
for | for循环,常用于有序序列的遍历 |
goto | 保留关键字 |
if | 某种条件的判定 |
implements | 实现接口,即实现接口文件中定义的空方法 |
import | 导入其他package中的类,用于跨包间的代码调用 |
instanceof | 判断某个对象是否属于某种类型 |
int | 整型数据类型 |
interface | 接口,声明一些空方法,待实现该接口的类去实现 |
long | 长整型数据类型 |
native | 代表调用本地C语言实现的接口 |
new | 创建对象 |
package | java语言中组织代码的一个单位 |
private | 私用,代表最低的访问优先级 |
protected | 被保护的,代表有继承等关联关系等的访问优先级 |
public | 公共的,代表最高访问优先级 |
return | 返回,结束方法 |
short | 短整型数据类型 |
static | 静态 |
super | 表示父类 |
switch | 多条件分支判定 |
synchronized | 同步,代表要保证线程安全 |
this | 表示当前类 |
throw | 抛出某个具体异常 |
throws | 声明在当前定义的成员方法中所有需要抛出的异常 |
transient | 表示不需要被序列化 |
try | 用于try…catch语句 |
void | 表示该方法无返回值 |
volatile | 表明两个或者多个变量必须同步地发生变化 |
while | 用于while和do…while循环语句中 |
8.2 部分重要关键字
8.2.1 abstract
abstract代表抽象,可以修饰类和方法。
abstract修饰方法时,代表抽象方法。抽象方法的特点:
1>抽象方法没有自己的方法体;
2>抽象方法不能用private修饰,因为抽象方法必须被子类实现(覆写),而private权限对于子类来说是不能访问的,所以就会产生矛盾;
3>抽象方法也不能用static修饰,如果用static修饰了,就可以直接通过类名调用,而抽象方法压根就没有任何实现,这样的调用是没有意义的。
abstract修饰类时,代表抽象类。抽象类的特点:
1>抽象类不能被实例化,也就是说我们没法直接new一个抽象类,抽象类只能由它的继承类实例化;
2>抽象类虽然不能被实例化,但有自己的构造方法;
3>抽象类与接口(interface)有很大的不同之处,接口中不能有实例方法去实现业务逻辑,而抽象类中可以有实例方法,并实现业务逻辑,比如可以在抽象类中创建和销毁一个线程池;
4>抽象类不能使用final关键字修饰,因为final修饰的类是无法被继承,而对于抽象类来说就是需要通过继承去实现抽象方法,这又会产生矛盾。
抽象类和抽象方法的关系:
1>如果一个类中至少有一个抽象方法,那么这个类一定是抽象类,但反之则不然。也就是说一个抽象类中可以没有抽象方法。这样做的目的是为了此类不能被实例化。
2>如果一个类继承了一个抽象类,那么它必须全部覆写抽象类中的抽象方法,当然也可以不全部覆写,如果不覆写全部抽象方法则这个子类也必须是抽象类。
8.2.2 final
final代表最终的、不可更改的,可以修饰变量、方法和类。
final修饰变量时, 如果引用为基本数据类型,则该引用为常量,该值无法修改;如果引用为引用数据类型,比如对象、数组,则该对象、数组本身可以修改,但指向该对象或数组的地址的引用不能修改;如果引用时类的成员变量,则必须当场赋值,否则编译会报错。
当final变量是基本数据类型以及String类型时,如果在编译期间能知道它的确切值,则编译器会把它当做编译期常量使用。也就是说在用到该final变量的地方,相当于直接访问的这个常量,不需要在运行时确定。
final修饰方法时,表示该方法无法被子类重写,但是可以被继承。
final修饰类时,表示该类无法被继承,同时类中的所有成员方法都会被隐式定义为final方法(只有在需要确保类中的所有方法都不被重写时才使用final修饰类)。
8.2.3 static
static关键字主要用来修饰成员变量和成员方法,在《Java编程思想》中对static关键字有如下阐述:
static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途。
简言之,使用static的目的是为了在不创建对象的前提下来调用方法/变量。
static修饰方法时,该方法称为静态方法。在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法/变量的。
static修饰变量时,称为静态变量。静态变量在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。static成员变量的初始化顺序按照定义的顺序进行初始化。
除了修饰变量和方法外,static还可以修饰代码块,称为静态代码块。一个类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。为什么说static块可以用来优化程序性能,是因为它的特性:只会在类加载的时候执行一次。
static是不允许用来修饰局部变量。
静态成员变量虽然独立于对象,但是不代表不可以通过对象去访问,所有的静态方法和静态变量都可以通过对象访问(只要访问权限足够)。
此处提一下类的初始化顺序:
1>父类静态变量
2>父类静态代码块
3>子类静态变量
4>子类静态代码块
5>父类普通变量
6>父类普通代码块
7>父类构造函数
8>子类普通变量
9>子类普通代码块
10>子类构造函数
总结下,static关键字特点:
1>static是一个修饰符,用于修饰成员。(成员变量,成员函数)static修饰的成员变量 称之为静态变量或类变量。
2>static修饰的成员被所有的对象共享。
3>static优先于对象存在,因为static的成员随着类的加载就已经存在。
4>static修饰的成员多了一种调用方式,可以直接被类名所调用,(类名.静态成员)。
5>static修饰的数据是共享数据,对象中的存储的是特有的数据。
成员变量和静态变量的区别:
1>生命周期的不同:
成员变量随着对象的创建而存在随着对象的回收而释放。
静态变量随着类的加载而存在随着类的消失而消失。
2>调用方式不同:
成员变量只能被对象调用。
静态变量可以被对象调用,也可以用类名调用。(推荐用类名调用)
3>别名不同:
成员变量也称为实例变量。
静态变量称为类变量。
4>数据存储位置不同:
成员变量数据存储在堆内存的对象中,所以也叫对象的特有数据。
静态变量数据存储在方法区(共享数据区)的静态区,所以也叫对象的共享数据。
静态使用时需要注意的事项:
1>静态方法只能访问静态成员。(非静态既可以访问静态,又可以访问非静态)
2>静态方法中不可以使用this或者super关键字。
3>主函数是静态的。
8.2.4 super
super用于在子类中指代父类对象。super的三种使用情况:访问父类的方法;调用父类构造方法;访问父类中的隐藏成员变量。
调用父类构造方法的两种情况:
1>直接调用super()会执行父类的无参构造方法,可以默认不写。
2>使用super(“父类参数”),调用父类有参构造方法,把参数传递进来就好。
父类只有带参构造器(无参构造器没有),子类必须有相同参数的构造方法。子类必须有相同参数的构造方法,并且还需要调用super(参数)。
8.2.5 this
super表示父类,this表示当前对象。
this访问本类中的属性,如果本类没有此属性则从父类中继续查找。
this访问本类中的方法,如果本类没有此方法则从父类中继续查找。
this调用本类构造,必须放在构造方法的首行。super调用父类构造,必须放在子类构造方法首行。
this和super的联系:
1>在对拥有父类的子类进行初始化时,父类的构造方法也会执行,且优先于子类的构造函数执行;因为每一个子类的构造函数中的第一行都有一条默认的隐式语句super();
(如果子类的构造方法中没有手动调用父类的构造方法,则会默认调用父类的无参构造方法)
2>this() 和super()都只能写在构造函数的第一行;
3>this() 和super() 不能存在于同一个构造函数中。第一,this()和super()都必须写在构造函数的第一行;第二,this()语句调用的是当前类的另一个构造函数而这个另一个构造函数中必然有一个父类的构造器,再使用super()又调用一次父类的构造器, 就相当于调用了两次父类的构造器,编译器不会通过;
4>this和super不能用于static修饰的变量,方法,代码块;因为this和super都是指的是对象/实例。