1、关键字
定义:被java语言赋予了特殊含义的单词。main不是关键字。goto const是保留字
特点:字母均为小写
用于定义数据类型的关键字:class interface byte short char int float long
double boolean void
用于定义数据类型值: true false null
用于定义访问权限修饰符:public protected private
用于定义定义类,函数,变量修饰符的关键字:abstract final static synchronized
用于定义类与类之间的关系:extends implements
用于定义新建实例和引用实例,判断实例的关键字:new this super instanceof
用于异常处理的:throws throw try catch finally
用于包的关键字:package import
其他修饰符: native strictfp transient volatile assert
2、java中的常量分类
1 整数常量
2 小数常量
3 boolean型常量:true false
4 字符常量:单引号括起的单数字或字母或符号,如'a' '\t'
5 字符串常量:双引号标识的一个或多个字符,"h","hello woer"
5 null常量:只有一个数值,null
3、java中的8中基本数据类型
byte 1字节 char 2字节 short 2字节 int 4字节
float 4字节 long 8字节 double 8字节 boolean
PS:整数的默认类型是 int 小数的默认类型是 double
long l = 1234355654; //错误,超出int范围
long l = 1234355654L;//正确,加L使编译器知道数据类型是long
float f = 2.3;// 错误,默认小数数double
float f = 2.3f;//正确 ,加标识f
3种引用数据类型: 类 class 接口 interface 数组[]
常见错误: 1 定义long型数据,赋值时未加标识L
2 定义float,赋值或初始化没添加f,编译器识别为double型
3 定义变量后,未初始化即使用
int a; System.out.println(a);
4 使用不存在的变量或在变量作用域之外使用变量
4、类型转换
1 自动类型转换
int a = 3;
byte b = 2;
a = a + b;
运算时,b自动转换为int型 再与a相加
2 强制类型转换
运算时,数据类型不一致,需要进行手动强制转换
int a = 3;
byte b = 2;
b = (byte)(a + b);
(a+b)运算时,自动转换为int型,要将结果赋给byte型,必须强制转换
PS:1 非数值类型不能进行数学运算,如
int a = 2; boolean n = true;
a = a + n;//错误
2 char类型数据可以直接与int类型相加,但char类型数据会自动提升为int型
byte a = 0;
char b = 'a';
byte result = a + b;// 错误: 不兼容的类型: 从int转换到byte可能会有损失
____________________________________________________
int a = 97;
char b = 'a';
boolean res = (a==b);//true
总结:表达式的数据类型的自动提升;
1 所有的byte short char型自动提升为int型
2 提升等级 double -> float -> int,表达式中如果存在等级高的类型,则结果为等级高的类型
int a = 2;
float f = 2.1f;
long l = 2L;
double d = 2.0;
l = l + f;//错误: 不兼容的类型: 从float转换到long可能会有损失
f = f + l;
d = d + l;
f = f + d;//错误
PS: 表达式中只有常量与常量的运算时不会自动提升
class Test
{
public static void main(String[] args)
{
byte b = 3 + 7;
byte a = 3 + 'a';
System.out.println(b+"..."+a);
byte b1 = 3;
byte b2 = 7;
byte b3 = b1 + b2;//错误
}
}
输出结果:10...100
错误原因:涉及到编译器编译程序时候的细节,之所以byte b = 3 +7;,没有报错,是因为3和7都是
常量,编译器知道结果是10,并且在byte范围之内,因此就自动进行了强转,所以不会报错。 而b = b1
+ b2;中b1和b2都是变量,编译器编译程序是一行一行编译的,它根本不知道b1和b2到底是多少,两个
byte类型的数据相加时,首先都会被提升为int类型,他们的和也是int类型,其值可能会超过byte的范
围,因此就会报错。
5、b = a++;(假设数据都是整型)语句在计算机中的实际执行:
说明:计算机中的实际操作为:当执行b = a++;语句时,先把a放在一个临时内存空间中,然后将a自
加1,再将临时内存空间中的a赋值给b,因此b还是原来的a的值。
代码表现: int temp = a; //将a的值存至临时内存
b = temp; //a的值赋给b
a = a + 1; //变量a加1
6、short s = 3; 则语句 s += 4;和语句 s = s + 4; 的区别:
1 在执行s+=4;语句时,编译器在编译的时候,默认进行了强制类型转换,也就是将int类型的数
据转换成short类型的数据。
2 在执行s = s + 4;语句时,编译器在编译的时候,默认并没有强制类型转换。 所以,s是short类
型,4是int类型,s会自动提升为int类型,相加的和也是int类型,赋值给short类型的变量肯定会损失精
度。 这时候就需要进行强制类型转换:s = (short)(s + 4);。
7、逻辑运算符&和&&,以及|和||的区别。
&&:和&运算的结果是一样的,但是运算过程有点小区别。
&:无论左边的运算结果是什么,右边都参与运算。
&&:当左边为false时,右边不参加运算,这样可以提升效率。
||:和|运算的结果是一样的,但是运算过程有点小区别。
|:无论左边的运算结果是什么,右边都参与运算。
||:当左边为true时,右边不参加运算,这样可以提升效率。
使用&&和||比使用&和|更高效一些。
8、位运算符
<< 左移操作 高位丢弃,空缺补0
>> 右移 空缺位补上符号位的数字
>>> 无符号右移 空缺位补0,跟符号位无关
& 按位与
| 或
^ 异或
~ 取反
PS: 1 & 操作常用于截取某几位二进制数,比如截取一个整数的末8位
int a = 512;
int b = a&0Xff;//截取a末8位
2 一个数疑惑另一个数两次,结果还是这个数
6^3^3 = 3;
技巧:
利用异或运算可以实现对数据简单地进行加密,例如对一幅图片
的所有数据异或3进行加密,那么这幅图片就无法查看了。 解密
只需要再对图片的数据执行异或3操作即可。
3 整数左移以为相当于乘以2,右移一位相当于除以2
8>>1 = 4;
8<<1 = 16;
4 移位运算只能对整形数据 short byte char int long进行操作
9、switch 语句的特点:
1 switch语句选择的类型只有四种:byte short int char
switch语句的表达式可以是byte吗?可以是long吗?可以是String吗?
可以, 不可以, JDK7以后可以,JDK5支持枚举类型
2 case 和 default 没有顺序,先执行第一个case,没有匹配的case时才执行default
3 swittch语句结束的两种情况: 1 遇到 break
2 执行到switch结束
4 如果匹配的case 或 default 没有对应的break;则程序顺序执行下去,直到遇到break或者switch结束
5 进入switch语句后,执行顺序是先执行case,然后从上往下,最后执行default,
即使default在case前面,执行顺序也不变。
6 case后面只能是常量,不能是变量,而且,多个case后面的值不能出现相同的
int a = 'b';
switch(a){
case 'a':
System.out.println("a");
break;
case 98:
System.out.println("b");
执行结果: b
10、if和switch语句的应用:
if:
1. 对具体的值进行判断。
2. 对区间判断。
3. 对运算结果是boolean类型的表达式进行判断。
switch:
1. 对具体的值进行判断。
2. 值的个数通常是固定的。
对于几个固定的值判断,建议使用switch语句,因为switch语句会将具体的答案都加载进内存,效率相对
高。
11、while 和 do..while 的区别
do while语句的特点:无论条件是否满足,循环体至少执行一次。
while如果条件不满足,循环体一次都不会执行。
12、for 语句表达式
for(初始表达式1,初始表达式2... ; 循环条件表达式 ; 循环后表达式)
{
执行语句;
......(循环体)
}
特点:初始表达式只执行一次,判断循环条件,如果条件位true,则执行循环体,
循环体执行完后,执行循环后表达式(循环体不执行时,循环后的表达式也不会被执行)。
接着继续判断循环条件,重复找个过程,直到条件不满足为止。
class Test
{
public static void main(String[] args)
{
for(int i = 1;i <= 5; i++){
for(int j = 1;j<i;j++)
System.out.print(" ");
for(int a = 1;a<=6-i;a++)
System.out.print("* ");
System.out.println();
}
}
}
运行结果: * * * * *
* * * *
* * *
* *
*
13、break 和 continue 语句
break语句:
应用范围:选择结构和循环结构。
continue语句:
应用范围:循环结构。
continue语句是结束本次循环继续下次循环。
PS:
1 这两个语句离开应用范围,存在是没有意义的。
2 这个两个语句单独存在,下面都不可以有语句,因为执行不到。
注意:java程序中,当有永远不会被执行到的语句时,编译要报错!!
class Test
{
public static void main(String[] args)
{
for(int i = 1;i <= 5; i++){
break;
System.out.println();//错误: 无法访问的语句
}
}
}
3 标号的出现,可以让这两个语句作用于指定的范围。
class Test
{
public static void main(String[] args){
out:for(int x = 0; x < 3; x++){
in: for(int y = 0; y < 4; y++){
System.out.println("x = " + x);
break out ;//直接跳出最外层循环
}
}
}
}
输出结果: x = 0
14、函数应该注意的:
1 对于函数没有具体返回值的情况,返回值类型用关键字void表示,那么该函数中
的return语句如果在最后一行可以省略不写,或者写上return;
2 函数中只能调用函数,不可以在函数内部定义函数。 否则,编译时期就会报错。
3 定义函数时,函数的结果应该返回给调用者,交由调用者处理
15、函数的重载:
在同一个类中,存在同名函数,但是它们的参数(顺序、类型等)不同,即可重载
好处:方便与阅读,优化了程序设计
PS: 1 函数重载与返回类型无关,至于函数名字是否相同和参数列表有关
2 java是严谨性语言,如果函数调用出现不确定性,会编译失败
16、数组的定义:
概念:同一类型数据的集合。一个容器
格式1 元素类型[] 数组名 = new 元素类型[长度];
int[] arr = new int[3];
定义了一个数组,但是元素未指定具体值(有默认值)
class Test
{
public static void main(String[] sd)
{
int[] arr = new int[3];
for(int i:arr)
System.out.print(i+" ");
System.out.println();
}
}
输出结果: 0 0 0
String[] 默认值是 null
char[] 默认值是 \u0000(字符串结束标志)
格式2 元素类型[] 数组名 = new 元素类型[]{元素1,元素2,...};
int[] arr = new int[]{1,2,3};
定义容器,存储具体的数据,此时,不能再指定数组长度,否则报错
java程序在运行是,需要在内存中分配空间。为了提高运算效率,又对空间进行了
不同区域的划分,每一片区域都有特定的处理数据方式和内存管理方式。
内存的划分:
1 寄存器
2 本地方法去
3 方法区
4 栈内存:用于存储局部变量,当变量所属的作用域一旦结束,所占空间会自动释放。
5 堆内存:数组和对象,通过new建立的实例都存放在堆内存中
每一个实体都有内存地址值。
实体中的变量都有默认初始化值,根据类型的不同而不同。 整数类型是0,小数类型是0.0或0.0f,boolean类
型是false,char类型是'\u0000'。
如果将数组的引用实体设置为null,也就是实体不再被使用,那么会在不确定的时间内被垃圾回收器回收。
PS:1 空指针异常(NullPointerException):当引用型变量没有指向任何实体时,用其操作实体,就会发生该异常
String[] line = null;
System.out.println(line[0]);//NullPointerException
2 直接打印数组的引用变量,输出的是数组初始地址的哈希值。
class Test
{
public static void main(String[] sd)
{
int[] arr = new int[2] ;
System.out.println(arr);
}
}
输出结果: [I@659e0bfd
"[I"表示的是int类型数组,"@"后面的内容表示数组初始地址的哈希值
练习:二叉树查找数组中元素:
import java.util.Arrays;
class Test
{
public static void main(String[] args)
{
System.out.println(binarySearch(16));
}
public static int binarySearch(int num)
{
int[] arr = new int[]{1,5,8,11,12,14,15};
// return Arrays.binarySearch(arr,num);
int min,max,mid;
min = 0;
max = arr.length-1;
mid = (min +max)/2;
while(min <= max){
if(arr[mid]==num)
return mid;
else
{
if(num<arr[mid]){
max = mid-1;
}
else{
min = mid+1;
}
mid = (max+min)/2;
System.out.println("chang ...max = "+max+" min = "+min+" mid = "+mid);
}
}
return -(min+1);
}
}
*/