文章目录
Java知识点总结
基础知识
两种数据类型
-
1、引用数据类型: 数组、类、接口。
-
2、基本数据类型:
- 整型:byte、short、int、long (8位1个字节、16/2 、32/4、64/8)
- 浮点型:float、double(32/4 、64/8)
- 字符型:char(16/2)
- 布尔类型:boolean
-
级别从低到高为:
byte,char,short(这三个平级)–>int–>float–>long–>double
-
自动类型转换:从低级别到高级别,系统自动转的;
-
强制类型转换:什么情况下使用?把一个高级别的数赋给一个别该数的级别低的变量;
Java中默认整数为int类型, 小数为double类型;
字符char是否可以存放一个汉字?可以,因为一个字符占2个字节,一个汉字两个字节;
整型初始值默认0 浮点型默认0.0 布尔类型默认false 引用数据类型默认null -
数据类型特征表
类型 位数 最小值 最大值 默认值 其他 byte 8 -128(-2^7) 127(2^7-1) 0 有符号、二进制补码表示 short 16 -32768(-2^15) 32767(2^15-1) 0 有符号、二进制补码表示 int 32 -2^31 2^31-1 0 有符号、二进制补码表示 long 64 -2^63 2^63-1 0L(0l) 有符号、二进制补码表示 float 32 2^(-149) 2^128-1 0.0f 单精度、IEEE754标准 double 64 2^(-1074) 2^1024-1 0.0d 双精度、IEEE754标准 char 16 \u0000(0) \uffff(65535) \u0000(0) 单一的、Unicode字符 -
浮点数内存结构
类型 位数 符号位 指数位 尾数位 float 32 1 8 23 double 64 1 11 52
short s1=1; s1=s1+1;
这一句编译错误,因为执行s1+1返回的结果是int类型(执行隐式类型转换)。修改的话要强制转换为short型才可以。
short s1=1; s1+=4;
这一句没有任何问题。
标识符命名规则
- 可以由数字、字母、下划线、$符号组成,但是不能是关键词,不能以数字开头
- 全局变量(成员变量、类变量)
- 可以供当前类的多个方法使用;
- 定义在类中;
- 成员变量存在于堆内存中,随着对象的产生而存在,消失而消失。
- 局部变量
- 定义在方法中或者方法参数
- 只能作用于当前方法
没有初始值
- 局部变量存在于栈内存中,随着所属区域的运行而存在,结束而释放。
- 常量: 只能声明在类中,使用final关键词声明,必须赋初始值,不能再次赋值;
Java中数据类型转换
- 隐式转换: 系统默认将其转换为我们需要的数据类型;
- 强制转换:=号两边数据类型不同时,可以通过,前面加(类型)转换
- 例如:int j=10;float f=100.123; int j=(int)f;
- 基本数据类型之间规则:
- (1)整型之间数据类型强制转换规则:long->int->short->byte
- (2)浮点型之间:double->float
- (3)char和整型 : 整型->char
- (4)char和浮点型: 浮点型->char
- (5)浮点型和整型 : (double/float)->(long/int/short/byte) 且小数点舍去
运算符
-
+
-
-
-
*
-
/
-
%
- 任何整数模2不是0就是1, 所以只要改变被模数就可以实现开关运算。
-
位运算符:用于操作二进制位的运算符。
&
|
^
<<
>>
>>>(无符号右移)
-
注意:
- (1)+号拼字符串:“字符串”+数字+数字 和"字符串"+(数字+数字)
- (2)分母不可以为0 否则报异常:ArithmeticException
- (3)java中数值运算时,位数多的与位数少的,做运算,最终结果类型为位数多的(long+double 返回double) 整型和浮点型运算,此时返回浮点型
- (4)java中1/2值为多少? 0
- (5)2的三次幂如何计算? 2<<2;
-
i++ 表示i先参与运算,然后在自身加1
-
++i 表示i先自身加1,然后在参与运算
-
类似的
--i
,i--
运算也是一样的注意!下面程序是否有错?
short i=10; i=i+1;(错误,因为需要强转 short+int结果还是int类型) i+=1;(正确)
-
逻辑运算符(也叫作短路运算符):
-
||
或,两边条件有一个满足true,则结果为true
-
&&
与, &&两边条件必须返回boolean类型,两边同时为true则结果为true
-
int n=10;
int m=100;
boolean f_2=(n>m)&&((n=100000)<100);
System.out.println(n);//n的值还是10
boolean f_3=(m>n)||((n=100000)<100); //n的值还是10
^:异或:和或有点不一样。
两边结果一样,就为false。
两边结果不一样,就为true.
& 和 &&区别: & :无论左边结果是什么,右边都参与运算。
**&&:**短路与,如果左边为false,那么右边不参数与运算。
| 和|| 区别:|:两边都运算。
||:短路或,如果左边为true,那么右边不参与运算。
判断语句&循环语句break&continue
- 判断语句
if(条件){}
- switch选择判断语句
- 循环语句
for(;条件;){循环体}
while(){}
do{}while()
- break 表示退出整个循环或者判断。break语句单独存在时,下面不要定义其他语句,因为执行不到,编译会失败。当循环嵌套时,break只跳出当前所在循环。要跳出嵌套中的外部循环,只要给循环起名字即可,这个名字称之为标号。
- continue 只能用于循环体中,表示退出当前循环,继续下一次循环。作用:结束本次循环,继续下次循环。该语句单独存在时,下面不可以定义语句,执行不到。
switch语句不能作用于long类型中,可以作用于char, byte, short, int, Character, Byte, Short, Integer, String or an enum.
这些语句什么时候用?
1)当判断固定个数的值的时候,可以使用if,也可以使用switch。
但是建议使用switch,效率相对较高。
switch(变量){
case 值:要执行的语句;break;
…
default:要执行的语句;
}
工作原理:用小括号中的变量的值依次和case后面的值进行对比,和哪个case后面的值相同了
就执行哪个case后面的语句,如果没有相同的则执行default后面的语句;
细节:a:break是可以省略的,如果省略了就一直执行到遇到break为止;
b:switch 后面的小括号中的变量应该是byte,char,short,int四种类型中的一种;
c:default可以写在switch结构中的任意位置;如果将default语句放在了第一行,则不管expression与case中的value是否匹配,程序会从default开始执行直到第一个break出现。
2)当判断数据范围,获取判断运算结果boolean类型时,需要使用if。
3)当某些语句需要执行很多次时,就用循环结构。 while和for可以进行互换。
区别在于:如果需要定义变量控制循环次数。建议使用for。因为for循环完毕,变量在内存中释放。
Java的核心包:即java.lang包
lang包下的String类,是不可以被继承的
查API可以发现,String类是final类
基本类型的包装类
把基本类型当做对象来使用
byte – Byte
short – Short
int – Integer
long – Long
float – Float
double – Double
char – Character
boolean – Boolean
1. 数字父类Number
子类:Byte,Short,Integer,Long,Float,Double,BigDecimal,BigInteger
取出基本类型值的方法
byteValue(),shortValue(),intValue(),longValue(),floatValue(),doubleValu()
2. Intger类
创建Integer对象: a= { value:6}
Integer a = new Integer(6);
Integer a = Integer.valueOf(6);
Integer 类中存在256个Integer缓存对象,封装-127到128;如果访问指定范围内的值,会访问缓存对象,如果超出范围,会新建对象。
3. Integer类的方法
字符串解析成int
Integer.parseInt();Byte.parseByte()……
Integer.toBinaryString() 转成二进制字符串
Integer.toOctalString() 转成八进制字符串
Integer.toHexString(255) 转成十六进制字符串
4. BigDcimal和BigInteger 类
BigDcimal精确的浮点数运算
BigInteger 超大的整数运算
创建对象:
BigDecimal bd = BigDecimal.valueOf(2);
方法:
- add(BigDecimal bd)
- subtract(BigDecimal bd)
- multiply(BigDecimal bd)
- divide(BigDecimal bd)
- divide(BigDecimal bd,保留位数,舍入方式)
- setScale(保留位数,舍入方式)
5. 自动装箱,自动拆箱
基本类型值,自动装箱成包装对象
Integer a = 6; 编译器编译成: Integer a = Integer.valueOf(6);
自动拆箱(自动拆箱要注意null值)
int i = a; 编译器编译成: int i = a.intValue();
- 注意异常! NumberFormatException
==比较和equals比较
- ==比较即比较内容也比较地址是否相同;
- equals方法,比较两个对象内容是否相同
注意:
- (1)字符串比较,不允许用== ,只能通过equals方法
- (2)如果Integer和Integer/int比较具体是否相等,此时绝对不允许使用==
Integer a = 127;
Integer b = 127;
System.out.println(a==b);true
//超一个字节会重新分配空间
Integer c = 128;
Integer d = 128;
System.out.println(c==d);false
String str="10";
Integer m=10;
System.out.println(m.equals(str));//false
System.out.println(m.toString().equals(str));//true
String str1 ="abc";
String str2 ="abc";
System.out.println(str2==str1);
System.out.println(str2.equals(str1));
String str3 =new String("abc");
String str4 =new String("abc");
System.out.println(str3==str4);
System.out.println(str3.equals(str4));
结果是true,true, false, true.前两个String对象从String池中获取,后两个对象是新创建的,内容相同但引用不同。
String
-
不属于基本类型
-
创建
String s1="ss"; //先将"ss"存储在池中,然后返回引用 String s2=new String("ss"); //创建新对象,使用的"ss"已经在池中 String s3="Prog"+"gramming"; //创建3个对象,均存储在池中
-
字符串的常量池
String s1 = “abcd” 字符串的字面值写法。第一次使用一个字符串字面值时,会在字符串常量池中新分配内存,再次使用相同字面值时,直接访问常量池中存在的对象,而不会重复创建 -
字符串常量池和不可变(Immutable)字符串
字符串的分配,和其他的对象分配一样,耗费高昂的时间与空间代价。JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化。为了减少在JVM中创建的字符串的数量,字符串类维护了一个字符串池,每当代码创建字符串常量时,JVM会首先检查字符串常量池。如果字符串已经存在池中,就返回池中的实例引用。如果字符串不在池中,就会实例化一个字符串并放到池中。Java能够进行这样的优化是因为字符串是不可变的,可以不用担心数据冲突进行共享。
String str1 = "str"; String str2 = "ing"; String str3 = "str" + "ing"; String str4 = str1 + str2; System.out.println(str3 == str4); String str5 = "string"; System.out.println(str3 == str5);
结果是false,true。后一个结果应该很好理解,因为第3行代码执行时已经将"string"存储在常量池中,第6行代码返回的是常量池中同一字符串"string"的引用,所以结果为true。前一个结果可能有点疑惑,后来把这段代码编译反汇编后发现执行第3行代码时是直接生成的String对象,内容为"string";而执行第四行代码时是借助new StringBuilder().append(“str”).append(“ing”).toString(),关键在于StringBuilder中定义的toString()方法,返回的是一个重新创建的String对象,并没有存在池中,所以前一个结果为false。
//StringBuilder.toString()源代码 public String toString() { // Create a copy, don't share the array return new String(value, 0, count); }
-
基本数据类型封装类的parse方法可能会报NumberFormatException,比如
Integer.parseInt("era");
-
intern()方法:若由equals()判断池中包含相同的对象则返回池中该对象的引用,否则将新对象加入池中并返回引用。注意不管是怎么创建的,都先从池里找。
-
对于字符串拼接,考虑性能,如果循环进行拼接操作,生成的字符串都会存在池里,并且每次拼接都要重新构造StringBuilder对象,影响性能。因此可以使用StringBuilder优化:
StringBuilder builder...append(String.valueOf("fsdasf"));
-
StringBuilder: 可变的字符序列,封装char[]数组,提供了一组方法,可以对内部封装的字符进行修改,常用来代替字符串做高效的字符串连接
- append() 追加字符内容,内部数组默认初始容量16,放满后翻倍+2;
- delete(start,end) 删除区间(start,end);
- deleteCharAt(i)删除指定位置 i;
- insert(i,内容) 在指定位置插入内容;
- insertCharAt(i,字符)在指定位置插入单个字符;
- replace(start,end,内容)替换指定范围的内容;
StringBuilder和StringBuffer
StringBuilder:线程不安全,效率高;JDK1.5版本后的新类。
StringBuffer:线程安全,旧版本的类。
-
StringBuilder/StringBuffer
- StringBuilder线程不安全,但效率高;
- StringBuffer线程安全,但效率低。
线程安全:某个函数、函数库在多线程环境中被调用时,能够正确地处理多个线程之间的共享变量,使程序功能正确完成
字符串的常用方法
- charAt(i) 获取指定位置的字符
- length() 字符串长度,字符的数量
- indexof()找第一个子串出现的初始位置,找不到返回-1
- indexof(子串,start)从执行位置向后找
- lastIndexof(子串) 从后向前找
- subString(start)截取start到末尾
- subString[start,end )截取[start,end )范围
- trim()去除两端的空白字符
- matches()用来判断是否匹配正则表达式
数组
- 先定义、开辟空间、赋值在使用
- java中数组长度不可变
- 数组下标从0开始
- 数组的定义:
- (1)
String[] items_0=null;//先定义 items_0=new String[4];//开辟空间
- (2)
String[] items_1=new String[4];
- (3)
String[] items_2={"JONES","SMITH","XIAOMING","SMI"};
- (4)
String[] items_3=new String[]{"SMITH","JINES","DSFDSF"};
- (1)
如何不通过第三个变量交换两个变量的值?
int a=10;
int b=20;
a=a+b;//a:30 b:20
b=a-b;//a:30 b:10
a=a-b;//a:20 b:10
二维数组:
String[][] items=new String[2][3];
//items[0]={"","",""};错误的
// items[0]=new String[4];对
-
数组的复制
System.arraycopy(strArr,0, strArr1, 0, 3);//从左到右参数意义:从哪个数组,从哪开始复制,复制到哪?开始位置,复制多长
System.out.println("copyOf复制:"+Arrays.toString(Arrays.copyOf(strArr, 3)));
-
数组的排序
Arrays.sort(strArr1);
Arrays 数组工具类
- Arrays.toString(数组) 把数组数据连接成字符串。
- Arrays.sort(数组) 数组排序 基本类型:优化的快速排序;引用类型:优化的合并排序。
- Arrays.binarySearch(数组,目标值) 二分法查找,在有序数组中查找目标值下标,找不到返回 -(插入点+1)。
- Arrays.copyof(数组,长度) 复制数组成一个指定长度的新数组。
数组 复制 - Arrays.copyof(数组,长度) 复制数组成一个指定长度的新数组
- System.arraycopy(原数组,原数组起始位置,目标数组,目标数组起始位置,复制的数量) ——不会创建新的数组,目标数组要事先存在。
数组越界,抛出ArrayIndexOutOfBoundsException
函数
为了提高代码的复用性,可以将其定义成一个单独的功能,该功能的体现就是java中的函数。函数就是体现之一。
java中的函数的定义格式:
修饰符 返回值类型 函数名(参数类型 形式参数1,参数类型 形式参数1,…){
执行语句;
return 返回值;
}没有具体的返回值时,返回的返回值类型用void关键字表示。
如果函数的返回值类型是void时,return语句可以省略不写的,系统会帮你自动加上。
**return的作用:**结束函数。结束功能。
如何定义一个函数?
函数其实就是一个功能,定义函数就是实现功能,通过两个明确来完成:
1)、明确该功能的运算完的结果,其实是在明确这个函数的返回值类型。
2)、在实现该功能的过程中是否有未知内容参与了运算,其实就是在明确这个函数的参数列表(参数类型&参数个数)。
函数的作用:
1)用于定义功能。
2)用于封装代码提高代码的复用性。
注意:函数中只能调用函数,不能定义函数。
函数定义名称是为什么呢?
答:1)为了对该功能进行标示,方便于调用。
2)为了通过名称就可以明确函数的功能,为了增加代码的阅读性。
重载的定义是:在一个类中,如果出现了两个或者两个以上的同名函数,只要它们的参数的个数,或者参数的类型不同,即可称之为该函数重载了。
**如何区分重载:**当函数同名时,只看参数列表。和返回值类型没关系。
类
- 属性:即一类事物具有的共有特点或者特性;程序中为全局变量(成员变量)
- 方法:一类事物具有的动作;
- 类的定义和使用
- class 类名称{
属性
方法
} - 使用关键字new就可以创建类对象,使用对象.方法,对象.属性就可完成调用
- 创建一个对象都在内存中做了什么事情?
- 1:先将硬盘上指定位置的class文件加载进内存。
- 2:执行main方法时,在栈内存中开辟了main方法的空间(压栈-进栈),然后在main方法的栈区分配了一个变量p。
- 3:在堆内存中开辟一个实体空间,分配了一个内存首地址值。new
- 4:在该实体空间中进行属性的空间分配,并进行了默认初始化。
- 5:对空间中的属性进行显示初始化。
- 6:进行实体的构造代码块初始化。
- 7:调用该实体对应的构造方法,进行构造方法初始化。()
- 8:将首地址赋值给p ,p变量就引用了该实体。(指向了该对象)
- class 类名称{
抽象类: abstract
- 抽象类的特点:
- 1:
抽象方法只能定义在抽象类中
,抽象类和抽象方法必须由abstract关键字修饰(可以描述类和方法,不可以描述变量)。 - 2:抽象方法只定义方法声明,并不定义方法实现。非抽象的方法可以定义方法实现
- 3:抽象类不可以被创建对象(实例化)。
- 4:只有通过子类继承抽象类并覆盖了抽象类中的所有抽象方法后,该子类才可以实例化。否则,该子类还是一个抽象类。
- 1:
- 抽象类的细节:
- 1:抽象类中是否有构造方法?有,用于给子类对象进行初始化。
- 2:抽象类中是否可以定义非抽象方法?可以。其实,抽象类和一般类没有太大的区别,都是在描述事物,只不过抽象类在描述事物时,有些功能不具体。所以抽象类和一般类在定义上,都是需要定义属性和行为的。只不过,比一般类多了一个抽象方法。而且比一般类少了一个创建对象的部分。
- 3:抽象关键字abstract和哪些不可以共存?final ,private , static
- 4:抽象类中可不可以不定义抽象方法?可以。抽象方法目的仅仅为了不让该类创建对象。
- 5:抽象类中可以有普通的成员变量
- 6:抽象类中可以有静态方法
接口:interface
- 接口的特点:
- 1、接口是特殊抽象类,所有方法都是抽象方法,都是public访问权限,数据成员都是public,static,final 注意:1.8以后接口中是可以定义普通的方法,也是可以有方法体的
- 2、不能被实例化,方法abstract关键词可以省略,但实际上还是抽象方法
- 3、变量都是常量,省略final关键词;
- 4、接口不能被实例化,只能通过implements来实现接口,一个实现类,可以实现多个接口
- 5、接口可以继承接口。
- 6、实现以后要重写所有抽象方法,包括接口继承接口中的抽象方法
- 7、接口中不能有构造方法
- 接口的好处:
- 1、java由于单继承,接口可以弥补无法多继承的缺点
- 2、好的程序要求高内聚低耦合,接口可以实现程序的解耦
- 3、定义一种规范
class A implements X,Y,Z {}
class A extends B implements X,Y,Z {}
抽象类和接口的区别
-
抽象类只能被继承,而且只能单继承。
-
接口需要被实现,而且可以多实现。
-
抽象类中可以定义非抽象方法,子类可以直接继承使用。
-
接口中都有抽象方法,需要子类去实现。
-
抽象类使用的是 is a 关系。
-
接口使用的 like a 关系。
-
抽象类的成员修饰符可以自定义。
-
接口中的成员修饰符是固定的。全都是public的。
-
抽象类可以有构造方法,接口中不能有构造方法
-
抽象类是一种对事物的抽象,而接口是一种对行为的抽象;
-
抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。
-
抽象类是一种模板式设计,而接口是一种行为规范,是一种辐射式设计。
模板式设计的含义是:如果B和C都使用了公共模板A,如果他们的公共部分需要改动,那么只改动A就可以了;
辐射式设计的含义是:如果B和C都实现了公共接口A,如果现在要向A中添加新的方法,那么B和C都必须进行相应改动。
-
抽象类中可以有普通成员变量,接口中没有普通成员变量
内部类
定义在类内部、方法内部或局部代码块内部的类,用来辅助外部实例运算,封装局部数据,或局部的运算逻辑。
非静态内部类、属于实例的内部类 非静态内部类实例,必须依赖于一个外部类的实例才能存在。
静态内部类 静态内部类,与普通的类没有区别。
局部内部类
局部定义的类型,类似于局部变量,有作用范围,只能在局部代码块内使用这种类型
局部内部类中,使用外面的局部变量,必须加 final,jdk1.8,缺省。
匿名内部类
Weapon w = new Weapon() {...};
{} - 匿名类
new - 新建匿名类的实例
Weapon - 父类型
() - super(),可传参数super(1,2,3)
static
- static 声明方法为静态方法(静态方法只能访问静态成员。(非静态既可以访问静态,又可以访问非静态)),声明属性为静态属性;
- static 关键词:
- 1、static 修饰方法,该方法叫做静态方法(也叫做类方法),可直接通过这个类的类名打点直接调用;
- 2、静态方法中不能使用this/super关键词,静态方法不能直接调用当前类中的非静态方法(或非静态属性),必须通过new实例化后在调用。
- 3、static声明的方法和属性,该对象已经被实例化,且只能被实例化一次(单例模式)
- 4、static修饰的属性,被相同类的不同实例所共享;
- 成员变量(没有特殊修饰)和静态变量的区别:
- 1、生命周期的不同:
成员变量随着对象的创建而存在,随着对象的回收而释放。
静态变量随着类的加载而存在,随着类的消失而消失。 - 2、调用方式不同:
成员变量只能被对象调用。
静态变量可以被对象调用,也可以用类名调用。(推荐用类名调用) - 3、别名不同:
成员变量也称为实例变量。
静态变量称为类变量。 - 4、数据存储位置不同:
成员变量数据存储在堆内存的对象中,所以也叫对象的特有数据。
静态变量数据存储在方法区(共享数据区)的静态区,所以也叫对象的共享数据。
- 1、生命周期的不同:
this
表示当前类对象,不能用于static声明的方法中, 常用于区分全局变量和局部变量同名
this(…):构造方法之间的调用,必须是首行代码,如果有多个构造方法,会通过this(…)调取下面的所有构造方法,完成赋值。
super
- (1)使用super关键字, super代表父类对象,只能用在子类中
- (2)可在子类构造方法中调用且必须是该方法中第一句
- (3)不能使用在static修饰的方法中
- (4)super的用处
- 访问父类构造方法
super();
super(name);
- 访问父类属性
super.name;
- 访问父类方法
super.print();
- 访问父类构造方法
final
-
1.修饰类
当用final修饰一个类时,表明这个类不能被继承。也就是说,如果一个类你永远不会让他被继承,就可以用final进行修饰。final类中的成员变量可以根据需要设为final,但是要注意final类中的所有成员方法都会被隐式地指定为final方法。
在使用final修饰类的时候,要注意谨慎选择,除非这个类真的在以后不会用来继承或者出于安全的考虑,尽量不要将类设计为final类。
-
2.修饰方法
下面这段话摘自《Java编程思想》第四版第143页:
使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了。
因此,如果只有在想明确禁止 该方法在子类中被覆盖的情况下才将方法设置为final的。
注:类的private方法会隐式地被指定为final方法。
-
3.修饰变量
对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。
访问修饰符
面向对象三个过程
- OOA面向对象分析
- OOD面向对象设计
- OOP面向对象编程
面向对象三个特性(属性)
- 继承
- 继承就是类之间的继承,使用extends来实现,从而实现代码的复用
- 多态
- 某一种事物有不同的具体的体现就是多态。
- 多态体现在:重写、重载、对象实例化。
- 多态的好处:提高了程序的扩展性。
- 多态的弊端:当父类引用指向子类对象时,虽然提高了扩展性,但是只能访问父类中具备的方法,不可以访问子类中特有的方法。(前期不能使用后期产生的功能,即访问的局限性)
- 封装
- 是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
- 好处:将变化隔离;便于使用;提高重用性;安全性。
- 封装原则:将不需要对外提供的内容都隐藏起来,把属性都隐藏,提供公共方法对其访问。
构造方法
- 该方法与类名相同;没有返回值也不可以使用void 声明
- 默认public修饰
- 任何一个类,都有一个无参数的构造方法; 对象实例化时被执行
- 构造方法和普通方法的区别
- 构造方法是在对象创建时,就被调用,构造方法常用于初始化成员变量,而且初始化动作只执行一次。
- 一般方法,是对象创建后,需要调用才执行,可以被调用多次。
如果说你编写了自己的构造方法,那么必须编写默认的无参构造方法
引用Java编程思想中的片段:
class Bush {
Bush(int i) {}
Bush(double d) {}
}
现在,假若使用下述代码:
new Bush();
编译程序就会报告自己找不到一个相符的构建器。就好象我们没有设置任何构建器,编译程序会说:“你看来似乎需要一个构建器,所以让我们给你制造一个吧。”但假如我们写了一个构建器,编译程序就会说:“啊,你已写了一个构建器,所以我知道你想干什么;如果你不放置一个默认的,是由于你打算省略它。”
程序的执行过程
-
单一类中:
- 1.初始化块2. 静态初始化块3.构造方法
- 执行顺序: 静态初始化块(永远只被执行一次) 初始化块 构造方法
-
父类和子类中都有静态代码块,非静态代码块,构造方法时。
- 初始化子类对象时,调用顺序: 父类静态,子类静态,父类非静态,父类构造,子类非静态,子类构造
-
静态域
- 其实最先初始化的并不是静态块,而是静态域,而静态域中包含静态变量、静态块和静态方法,其中需要初始化的是静态变量和静态块。而他们两个的初始化顺序是靠他们俩的位置决定的!
例如:
public class B { public static B t1 = new B(); public static B t2 = new B(); { System.out.println("构造块"); } static { System.out.println("静态块"); } public static void main(String[] args) { B t = new B(); } }
测试结果:构造块 构造块 静态块 构造块
方法重载:overload
- 当前类中方法名相同,参数个数或者参数类型不同;
- public String student(String name,int age){…}
public void student(int age,String name){…}
这个也是重载 - 为什么重载,重载有什么好处?
- 了解:好处便于记忆筛选,体现了java的多态
方法重写:override
- 发生在子类中,子类的方法与父类方法名、参数个数、参数类型,返回值类型完全相同,并且访问权限不能严于父类
- 什么时候使用重写?
- 1、当父类方法无法满足子类需求,此时可以在子类中重写父类方法
- 2、如果开发时,需要对父类方法功能拓展,此时还不想修改父类程序
则使用继承(定义一个类继承父类),然后通过子类重写该方法,
然后其他类进行调用这个子类方法;
继承
- 子类继承父类,可以继承父类中非私有的方法和属性;
- 构造方法无法被继承;
- final修饰的类无法被继承;
- Java中是单继承,所有类的超类(父类/基类)是java.lang.Object类
- 如果一个类既继承了一个类又实现了接口,那么次序是,先继承,后实现!!
- 子类被实例化时,先实例化父类对象
- java中是单继承,即一个类只能有一个父类;所有类的父类(超类)是java.lang.Object
- 继承的好处:
- 1、简化子类代码
- 2、使用继承可以不修改父类程序前提,完成对父类方法的拓展
- 缺点:
- 1、打破了封装(封装的目的是隐藏),父类向子类暴露了细节
- 2、过多的继承,会导致程序不便于维护
- 3、白盒重用,因为基类的内部细节通常对子类是可见的
所有类的父类Object类
- Object位于java.lang包下面
- 其中常用的方法有:
- toString(); 返回当前对象本身的有关信息,按字符串对象返回
- equals(); 比较两个对象是否是同一个对象,是则返回true
- hashCode(); 返回该对象的哈希代码值
- getClass(); 获取当前对象所属的类信息,返回Class对象
- equals方法的重写:
- 什么时候重写equals方法?
- 比较两个对象时候,需要重写equals方法,重新定义比较规则
- 什么时候重写equals方法?
- toString方法重写:
- 重写toString方法的目的是:让对象以某个字符串形式表示
主方法的分析
-
public static void main(String[] args){}
-
1)保证该类的独立运行。
-
2)它是程序的入口。
-
3)它被jvm调用。
- Public:访问权限最大。
- static:不需要对象,直接类名即可。
- void:主方法没有返回值。
- main:主方法特定的名称。
- (String[] args):主方法的参数,是一个字符串数组类型的参数,jvm调用main方法时,传递的实际参数是 new String[0]。
注意:主方法的存在,仅为该类是否需要独立运行,如果不需要,主方法是不用定义的。
Java内存的总结
- java分了5片内存
- 1:寄存器。
- 2:本地方法区。
- 3:方法区。
- 4:栈。
- 5:堆。
- 栈:存储的都是局部变量 ( 方法中定义的变量,方法上的参数,语句中的变量 );只要数据运算完成所在的区域结束,该数据就会被释放。
- 堆:用于存储数组和对象,也就是实体。啥是实体啊?就是用于封装多个数据的。
- 1:每一个实体都有内存首地址值
- 2:堆内存中的变量都有默认初始化值。因为数据类型不同,值也不一样。
- 3:垃圾回收机制。
方法区是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
自动装箱,自动拆箱
-
Java有8种基本类型,每种基本类型又有对应的包装类型。在Java中,一切都以对象作为基础,但是基本类型并不是对象,如果想以对象的方式使用这8中基本类型,可以将它们转换为对应的包装类型。基本类型和包装类型的对应
-
可以直接将整型赋给Integer对象,由编译器来完成从int型到Integer类型的转换,这就叫自动装箱。
-
与此对应的,自动拆箱就是可以将包装类型转换为基本类型,具体的转换工作由编译器来完成。
-
其他几种基本类型的转换也是类似的
Integer i = null;
int j = i.intValue();
编译通过,但运行时报错NullPointerException。因为调用了null.somemethod()。
自动装箱和拆箱
定义:基本数据类型和包装类之间可以自动地相互转换
理解:装箱就是自动将基本数据类型转换为封装类型,拆箱就是自动将封装类型转换为基本数据类型。
Integer i = 100; //自动装箱,编译器执行Integer.valueOf(100)
int j = i; //自动拆箱,编译器执行i.intValue()
Integer i1 =200;
Integer i2 =200;
System.out.println("i1==i2: "+(i1==i2));
Integer i3 =100;
Integer i4 =100;
System.out.println("i3==i4: "+(i3==i4));
运行结果为false,true.(自动调用Integer的valueOf()缓存(如果值大于127不会缓存)为基本类型)
正则表达式
一般用来判断用户的输入内容是否符合格式要求
- matches()字符串的方法,用来判断是否匹配
if(s.matches(regex)) {}
- split(正则):用匹配的子串来拆分字符串
String s = "aaa,bbb,ccc";
String[] a = s.split(",");
- replace(正则,子串)替换所有匹配的子串
异常和错误
-
Error(unchecked异常)
是程序无法处理的错误,通常发生于虚拟机自身,表示运行应用程序中较严重问题。例如,Java虚拟机运行错误(Virtual MachineError),当 JVM 不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError。这些异常发生时,Java 虚拟机(JVM)一般会选择线程终止。
-
Exception(checked异常)
必须处理的异常:Checked异常是Java特有的,在java设计哲学中,Checked异常被认为是可以被处理或者修复的异常,所以Java程序必须显式处理Checked异常,当我们使用或者出现Checked异常类的时候,程序中要么显式try- catch捕获该异常并修复,要么显式声明抛出该异常,否则程序无法通过编译。
-
Java中的异常
-
异常的种类:
- 1、编译时异常(非运行时异常)
- 程序编译过程中产生的, 如果有异常,则不会通过编译,必须手动的捕获异常或者继续抛出该异常;
- 2、运行时异常:
- 程序在运行过程中产生的,不需要手动抛出或者捕获,系统自动报出;
- 1、编译时异常(非运行时异常)
-
异常的处理
- 功能抛出几个异常,功能调用如果进行try处理,需要与之对应的catch处理代码块,这样的处理有针对性,抛几个就处理几个。
- 特殊情况:try对应多个catch时,如果有父类的catch语句块,一定要放在下面。用多个catch子句处理不同异常,级别由低到高。
-
throws 和throw
- throws 方法声明时使用,表示该方法可能产生的异常,抛出,谁调用谁捕获处理,throws用在函数上。
- throw方法体中使用,表示抛出一个具体的异常对象,谁调用谁捕获处理,throw用在函数内。
catch中存在return,此时finally中是否被执行?执行,但是finlly外面程序不会继续执行
try {
} catch(AException e) {
} catch(BException e) {
} catch(父类型Exception e) {
} finally {
不管出不出错,都会执行
}
如果抛出异常,并且catch中有return语句,这个return语句会先执行,执行之后将结果保
存在缓存中,再去查看是否有finally,如果有finally就先执行finally语句,之后再返回缓存中
return的值,如果finally中也有return,那么finally中的return会覆盖掉之前缓存中的return,
即最终会返回finally中的return值
泛型
- 了解泛型:泛指一种某一种数据类型;
一些常见符号的含义:
E - Element (在集合中使用,因为集合中存放的是元素)
T - Type(Java 类)
K - Key(键)
V - Value(值)
N - Number(数值类型)
? - 表示不确定的java类型
S、U、V - 2nd、3rd、4th types
Object跟这些标记符代表的java类型有啥区别呢?
Object是所有类的根类,任何类的对象都可以设置给该Object引用变量,使用的时候可能需要类型强制转换,但是用使用了泛型T、E等这些标识符后,在实际用之前类型就已经确定了,不需要再进行类型强制转换
集合
-
对线性表,链表,哈希表这些常用的数据结构,在进行Java开发时,JDK已经为我们提供了一系列相应的类来实现基本的数据结构。因此,我们一般的程序员不必自己开发相关的方法
-
集合(框架):java提供了一组对数组、链表数据结构操作的API,这组API即集合;存在于java.util
-
Collection接口有两个子接口:
-
Set 接口有两个常用实现类:
-
1、TreeSet
-
基于 TreeMap 的 NavigableSet 实现
。使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的 Comparator 进行排序,具体取决于使用的构造方法。
(来自jdk1.6)
- 自然排序:
>自然排序就是按字母书序排序,
比如 a->b->c…
0->1->2->3…
如果是字符串那么会按一个个的字母排序如果相等就比较下一个位置的字符, 知道比出大小位置
比如 abc->acd->ace->ade…
- 自然排序:
-
-
2、HashSet(Set最常用的实现类)
- 此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素。(来自jdk1.6)
-
Set接口特点
:
- Set 接口数据不重复(使用HashMap实例存储的,将存储对象作为key,通过equals方法比较,以及hashcode确认是否相同)
- Set 接口数据无序;
-
常用方法:add(E e)添加元素, iterator()获取迭代器
-
-
List 接口有三个常用实现类
-
1、ArrayList
- List 接口的大小可变数组的实现。实现了所有可选列表操作,并允许包括 null 在内的所有元素。 (来自jdk1.6)
-
2、LinkedList
- List 接口的链接列表实现。实现所有可选的列表操作,并且允许所有元素(包括 null)。 (来自jdk1.6)
-
3、Vector
-
Vector 类可以实现可增长的对象数组。与数组一样,它包含可以使用整数索引进行访问的组件。但是,Vector 的大小可以根据需要增大或缩小,以适应创建 Vector 后进行添加或移除项的操作。 (来自jdk1.6)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HMhTyHa9-1608257884614)(C:\Users\HW\AppData\Roaming\Typora\typora-user-images\image-20200821223653257.png)]
-
-
List接口的特点:
- 数据有序,数据允许重复的集合
- LinkedList:链表实现,插入,删除元素效率高,查询效率低,线程不安全
- ArrayList:数组实现, 插入,删除元素效率低,查询效率高,线程不安全
- Vector:数组实现,线程安全
-
常用方法:
- add(对象)添加元素
- get(下标)默认从0开始,获取元素
- remove(int index) remove(Object obj) 根据下标或者元素移除某一个对象
- addAll(Collection cl)将某个集合中元素,合并到当前集合中
- size()该集合长度 contains(Object obj)判断某个元素在该集合中是否存在
-
-
将List集合转为数组?
- list.toArray()
-
将数组转为List集合?
- Arrays.asList(objct …a)
-
-
Map接口有两个常用实现类:
-
HashMap
- 基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。(来自jdk1.6)
-
HashTable
- 此类实现一个哈希表,该哈希表将键映射到相应的值。任何非 null 对象都可以用作键或值。 (来自jdk1.6)
-
map接口的特点
- Map接口不是Cllection的子接口
- Map实现:key value 键值对形式存储数据
- HashTable:键值对不能为空,线程安全,效率低
- HashMap:键值对可以为空,线程不安全,效率高
-
常用方法
-
boolean containsKey(Object key) //测试指定对象是否为此哈希表中的键。
-
put(key,value)//存放数据
-
get(key)//获取元素
-
map效率“最高”的遍历方式:(在java8以后可以利用stream来遍历)
Set<Map.Entry<String, Object> > entrySet=map.entrySet(); Iterator<Map.Entry<String, Object>> ite=entrySet.iterator(); while(ite.hasNext()){ Map.Entry<String, Object> obj= ite.next(); String key=obj.getKey(); Object value=obj.getValue(); System.out.println(key+":"+value); }
-
-
线程
-
线程是操作系统调度的最小单元,也叫轻量级进程。同一进程可以创建多个线程,而他们都拥有各自的计算器、堆栈和局部变量等属性,并且能够访问共享的内存变量。
-
线程的5个状态
- 创建(New):使用new关键字创建一个线程
- 就绪(Ready):调用start方法,等待CPU调度
- 运行(Running):执行run方法
- 阻塞(Blocked):由于一些原因放弃CPU使用权,暂时停止执行
- 死亡(Dead):run方法执行完毕或者执行时产生异常
-
几个重要的名词区分
-
同步和异步
同步方法调用后必须等待方法返回才能执行后续行为;异步方法调用后可以立刻执行后续行为。
-
并发和并行
并行是真正意义上的多个任务同时执行;并发是支持处理多个任务,不一定要同时,多个任务可能是串行的,但每个任务只能获取CPU很短的占用时间,多个任务在很短的时间内交替执行。
我相信你已经能够得出结论——“并行”概念是“并发”概念的一个子集。也就是说,你可以编写一个拥有多个线程或者进程的并发程序,但如果没有多核处理器来执行这个程序,那么就不能以并行方式来运行代码。因此,凡是在求解单个问题时涉及多个执行流程的编程模式或者执行行为,都属于并发编程的范畴。
-
阻塞和非阻塞
阻塞是指某一线程访问一公共资源时其他线程必须等待该线程释放资源才可以使用,否则就要挂起线程等待;非阻塞是指线程之间不会发生资源争夺。
-
原子性
原子性是指一个操作是不可被中断的,即使多个线程是同时执行的。
-
可见性
可见性是指当某个线程修改了共享变量的值,其他线程能否立刻知晓。
-
有序性
**Java内存模型中的程序天然有序性可以总结为一句话:如果在本线程内观察,所有操作都是有序的;如果在一个线程中观察另一个线程,所有操作都是无序的。**前半句是指“线程内表现为串行语义”,后半句是指“指令重排序”现象和“工作内存和主内存同步延迟”现象。
Java中提供了关键字volatile和synchronized关键字来保证线程之间操作的有序性。volatile包含了禁止指令重排序的语义,并保证不同线程对同一变量操作时的可见性;synchronized关键字对同一时刻同一变量只允许一个线程对其进行lock操作。
-
-
线程创建
- 继承Thread类重写run()方法
- 匿名内部类,即在new Thread()后跟具体的定义体,其中重写了run()方法
- 实现Runnable接口,重写run()方法
-
开启线程的run()和start()方法区别
- run()方法不能新建一个线程,而是在当前线程中调用run()方法;
- start()方法新建一个线程并调用其run()方法。
-
终止线程不要使用stop()
一般情况下,线程在执行完毕后就会结束,无需手工关闭,但是我们也经常会创建无限循环的后台进程以持续提供某项服务,所以就需要手动关闭这些线程。
在JDK中也有终止线程的API,例如stop()方法,但是极度不推荐这个方法,因为stop()方法得到调用后,会强行把执行到一半的线程终止,可能会引起数据不一致问题。但是想要终止一个无限循环的线程应该怎么做?
我们推荐的做法是在类中添加一个isStop的布尔值属性,判断isStop为true则跳出循环体,线程执行完毕自动终止,就避免了数据不一致的问题。
-
wait() 和notify()
这两个方法不是Thread类特有的,而是所有类的父类Object中的。
当一个对象调用了wait方法后,如:objectA.wait(),当前线程就会在这个对象上等待,会释放该对象的锁,直到其他线程调用了objectA.notify()方法为止。
需要注意的是,wait和notify方法都必须获得对象的监视器(锁),在同步代码得到执行后也会释放对象的锁,所以必须被包含在对象的synchronzied语句中。 -
小题
public class WaitNotifyDemo { final static Object object = new Object(); public static class Thread1 extends Thread{ @Override public void run() { synchronized (object){ System.out.println(System.currentTimeMillis()+" 线程1开启。。"); try { object.wait(); //1.先获取object的锁,然后开始等待,并再次释放object的锁。 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(System.currentTimeMillis()+" 线程1结束。。"); //4f. 两秒后,线程2执行结束,线程结束,重新获得了object的锁,此句猜得到执行 } } } public static class Thread2 extends Thread{ @Override public void run() { synchronized (object){ System.out.println(System.currentTimeMillis()+" 线程2开启,并执行notify通知线程1 。。"); object.notify(); //2.获取object的锁成功,通知object的其他线程(即线程1),这里还未释放object的锁! System.out.println(System.currentTimeMillis()+" 线程2执行notify结束。。"); try { Thread.sleep(2000); //3. 使线程2暂停2秒,即2秒后线程2才能执行结束,才能把object的锁释放。 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(System.currentTimeMillis()+" 线程2结束。。"); } } } public static void main(String[] args) { Thread thread1 = new Thread1(); Thread thread2 = new Thread2(); thread1.start(); thread2.start(); } }
以上代码是一个关于wait和notify的示意代码,声明一个静态对象和两个静态内部类表示两个线程,连个线程分别在对象object的同步块中调用wait和notify方法,在线程1中调用了object的wait方法前需要先获取object的锁,然后进入线程等待,并释放锁;然后线程2的notify方法执行前需要获取object的锁,然后通知线程1。但是此时线程1仍然无法执行wait方法后面的代码,原因是线程2Thread.sleep(2000)使得线程2在2秒之后才能退出并且释放object的锁,也即线程1必须等待线程2的object同步代码块执行结束后才能获得锁,去继续执行下面的代码,具体的输出日志如下:
1510300350884 线程1开启。。 1510300350884 线程2开启,并执行notify通知线程1 。。 1510300350884 线程2执行notify结束。。 1510300352884 线程2结束。。 //2秒中之后线程2结束,释放object锁 1510300352885 线程1结束。。 //线程2释放锁之后,线程1获得锁,结束等待状态,继续向下执行。
-
生产者消费者问题(线程同步,互斥)
IO流
-
流:
- 流是一组有序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
-
Java中流的分类:
-
按照数据流向分:
- 输入流:相对于内存,向内存中写入;
- 输出流:相对于内存,从内存往外读;
-
按照流的数据传输的格式:
-
字节流:以字节为单位读取;一般用于读写文件,读写诸如图象或声音等的二进制数据。
-
字符流:以字符为单位读取;一般用于读写文件中文本内容
-
-
网络编程
Java建立TCP连接的步骤:
- 服务器实例化一个ServerSocket对象,通过服务器的特定端口通信;
- 服务器调用ServerSocket的accept()方法,一直等待直到客户端连接到服务器的端口为止;
- 服务器等待时,客户端实例化一个Socket对象,指定服务器地址和端口号请求连接;
- 客户端的Socket构造函数尝试连接到服务器指定端口,如果成功连接,在客户端创建一个Socket对象使得可以与服务器通信;
- 服务器端accept()方法返回一个新的socket引用,使得可以连接到客户端。
反射
Java的反射机制是指程序可以访问、检测并修改本身的状态或行为的一种能力,并能根据自身行为的状态和结果调整或修改应用所描述行为的状态和相关的语义。
通过反射机制,可以访问Java对象的属性、方法、构造方法、关键字、返回值等等。
实例操作:
- 获取Class对象
Class c = Class.forName("A");
Class c = A.class;
Class c = new A().getClass();
- 利用Class对象获取新实例
Object o = c.newInstance();
- 进行相关操作,比如获取属性、方法等等,例如
Field fs = c.getDeclaredFields()[0];
XML解析
- XML是一种可拓展文本标记语言;
- 常用于:数据存储、作为项目配置文件,系统之间数据传输的某种数据格式;
- 解析方式有:
- DOM
- jdk自带的解析方式,事件驱动,不灵活,解析大文件效率低
- SAX
- jdk自带的解析方式,树形结构方式解析操作xml,灵活,大文件效率高
- JDOM
- 第三方工具包
- DOM4J:第三方工具包,最常用的一种解析方式
- DOM
JDBC数据库连接
- java提供的一组操作数据库的API;
- 常用接口有:
- Connection、
- ResultSet、
- PreparedStatement、
- Statement
- 常用数据库驱动程序和url格式
- Oracle数据库:
- 驱动程序包名:ojdbc5.jar
- 驱动程序包名有可能会变
- 驱动类的名字:oracle.jdbc.driver.OracleDriver
- JDBC URL:jdbc:oracle:thin:@dbip:port:databasename
- JDBC URL中黑色字体部分必须原封不动的保留,为该驱动识别的URL格式。红色字体部分需要根据数据库的安装情况填写。其中各个部分含义如下:
- dbip 为数据库服务器的IP地址,如果是本地可写:localhost或127.0.0.1
- port 为数据库的监听端口,需要看安装时的配置,缺省为1521
- databasename 为数据库的SID,通常为全局数据库的名字
- 例如:
jdbc:oracle:thin:@localhost:1521:XE
- JDBC URL中黑色字体部分必须原封不动的保留,为该驱动识别的URL格式。红色字体部分需要根据数据库的安装情况填写。其中各个部分含义如下:
- 驱动程序包名:ojdbc5.jar
- Mysql数据库
- 驱动程序包名:mysql-connector-java-5.1.26-bin.jar
- 说明:驱动程序包名有可能会变
- 驱动类的名字:com.mysql.jdbc.Driver
- JDBC URL:jdbc:mysql://dbip:port/databasename
- JDBC URL中黑色字体部分必须原封不动的保留,为该驱动识别的URL格式。红色字体部需要根据数据库的安装情况填写。其中各个部分含义如下:
- dbip –为数据库服务器的IP地址,如果是本地可写:localhost或127.0.0.1
- port –为数据库的监听端口,需要看安装时的配置,缺省为3306
- databasename –数据库的名字。
- 例如:
jdbc:mysql://localhost:3306/XE
- JDBC URL中黑色字体部分必须原封不动的保留,为该驱动识别的URL格式。红色字体部需要根据数据库的安装情况填写。其中各个部分含义如下:
- 驱动程序包名:mysql-connector-java-5.1.26-bin.jar
- Oracle数据库:
期末题库
判断题
在异常处理中,若try中的代码可能产生多种异常则可以对应多个catch语句,若catch中的参数类型有父类子类关系,此时应该将父类放在后面,子类放在前面。( √ )
子类只能继承父类的public,protected和同一个包中的package级的成员。( √ )
在类中实现一个接口,则一定要实现接口中的所有方法。( × )
抽象方法不仅有方法头,还应该有方法体。( × )
拥有abstract方法的类是抽象类,但抽象类中可以没有abstract方法。
在比较str1和str2两个字符串对象值是否相等时使用语句str1==str2。( √ )
Java的源代码中定义几个类,编译结果就生成几个以.class为后缀的字节码文件。(√ )
Java程序里,创建新的类对象用关键字new,回收无用的类对象使用关键字free。 (× )
java自动回收机制
构造函数用于创建类的实例对象,构造函数名应与类名相同,返回类型为void。 (× )
构造函数无返回值
如果源文件包含import语句,则该语句必须是除空行和注释行外的第一个语句行。( √ )
静态初始化器是在其所属的类加载内存时由系统自动调用执行。 (√ )
在Java中对象可以赋值,只要使用赋值号(等号)即可,相当于生成了一个各属性与赋值对象相同的新对象。 (× )
Java applet也能够存取客户机磁盘上的文件。( √ )
Socket通常也称为套接字,用于描述IP地址和端口。 ( √ )
线程的优先级在1 至10之间,数值越小任务越紧急。( × )
线程的优先级用1-10之间的整数表示,数值越大优先级越高,即越高执行越快,默认的优先级为5。
并发就是事件、任务在同一时刻开始。( × ) (并行才是同一时刻开始)
在一个时间只能由一个线程访问的资源称为临界资源。访问临界资源的代码称为临界代码。( × )
多个线程间共享的数据称为临界资源
在Java的方法中定义一个常量要用const关键字。 ( 错 )
在异常处理中总是将可能产生异常的语句放在try块中,用catch子句去处理异常,而且一个try块之后只能对应一个catch语句。 错)
Applet是一种特殊的Panel,它是Java Applet程序的最外层容器。 ( 对 )
一个线程对象的具体操作是由run()方法的内容确定的,但是Thread类的run()方法是空的,其中没有内容;所以用户程序要么派生一个Thread的子类并在子类里重新定义run()方法,要么使一个类实现Runnable接口并书写其中run()方法的方法体。 ( 对 )
Java的字符类型采用的是Unicode编码,但所占字节由具体软硬件环境决定。 ( 错 )
所有的鼠标事件都由MouseListener监听接口的监听者来处理。 ( 错 )
Java语言中的数组元素下标总是从0开始,下标可以是整数或整型表达式。 ( 对 )
如果p是父类Parent的对象,而c是子类Child的对象,则语句p=c是正确的。 ( 错 )
Java程序里,创建新的类对象用关键字new,回收无用的类对象使用关键字free。 ( 错 )
由继承性可知,程序中子类拥有的成员数目一定大于等于父类拥有的成员数目。 (错 )
静态初始化器是在其所属的类加载内存时由系统自动调用执行。 ( 对 )
注释的作用是使程序在执行时在屏幕上显示//之后的内容。 ( 错 )
在异常处理中,若try中的代码可能产生多种异常则可以对应多个catch语句,若catch中的参数类型有父类子类关系,此时应该将父类放在后面,子类放在前面。 ( 对 )
URL在网络中是唯一的。( √ )(一个 URL 必须唯一地,永久地代表一个在线对象)
选择题
若需要定义一个类域或类方法,应使用哪种修饰符?( A )
A、static B、package C、private D、public
在浏览器中执行applet 程序,以下选项中的哪个方法将被最先执行( A )。
A、init() B、start() C、destroy() D、stop()
在使用interface声明一个接口时,只可以使用( D )修饰符修饰该接口。
A、private B、protected C、private protected D、public
Java源文件和编译后的文件扩展名分别为( B )
A.class 和java B.java 和class C.class和class D.java和java
在类中若要处理ItemEvent事件,则该类需要实现的接口是(A )
A.ItemListener B.ActionListener C. itemStateChanged D. Event
将GUI窗口中的组件按照从左到右如打字式排列的布局管理器是( A )
A.FlowLayout B.BorderLayout C.GirdLayout D.CardLayout
Java语言中,只限子类或者同一包中的类的方法能访问的访问权限是( C )
A、public B、private C、protected D、无修饰
private: Java语言中对访问权限限制的最窄的修饰符,一般称之为“私有的”。被其修饰的属性以及方法只能被该类的对象访问,其子类不能访问,更不能允许跨包访问。
default:即不加任何访问修饰符,通常称为“默认访问权限“或者“包访问权限”。该模式下,只允许在同一个包中进行访问。
protected: 介于public 和 private 之间的一种访问修饰符,一般称之为“保护访问权限”。被其修饰的属性以及方法只能被类本身的方法及子类访问,即使子类在不同的包中也可以访问。
public: Java语言中访问限制最宽的修饰符,一般称之为“公共的”。被其修饰的类、属性以及方法不仅可以跨类访问,而且 允许跨包访问。
在以下供选择的方法中,属于接口MouseMotionListener的方法是( D )
A、mouseReleased() B、mouseEntered() C、mouseExited() D、mouseMoved()
在编写访问数据库的Java程序时,ResultSet对象的作用是( D )
A、建立新数据库连接 B、用来表示与数据库的连接
C、在指定的连接中处理SQL语句 D、存储查询结果
关于方法main()的说法哪个正确?( C )
A.方法main()只能放在公共类中 B.main()的头定义可以根据情况任意更改
C.一个类中可以没有main()方法 D.所有对象的创建都必须放在main()方法中
this和super: ( C )
A.都可以用在main()方法中 B.都是指一个内存地址
C.不能用在main()方法中 D.意义相同
字符流与字节流的区别在于( D )
A.前者带有缓冲,后者没有 B.前者是块读写,后者是字节读写
C.二者没有区别,可以互换使用 D.每次读写的字节数不同
类B是一个抽象类,类C是类B的非抽象子类,下列创建对象x1的语句中正确的是( C )。(抽象类不能被实例化,即不能创建对象)
A.B x1= new B( ); B.B x1= C( );
C.C x1=new C( ); D.C x1= new B( );
线程对象的生命周期中,哪个不是其经历的状态( A )。
(五种基本状态:新建;就绪;运行;阻塞;死亡)
A.中断 B.运行 C.就绪 D.死亡
对于import java.awt.Button;以下那种说法错误( D )
A、Button属于java.awt包 B、Button在java.awt目录下
C、Button在java.awt文件中 D、Button属于Sun的类
用abstract定义的类( D )
A、可以被实例化 B、不能派生子类
C、不能被继承 D、只能被继承
每个使用组件的程序必须有一个( B )
A 、按钮 B 、容器 C 、菜单 D 、标签
在Java Applet程序用户自定义的Applet子类中,一般需要重载父类的( D )方法来完成一些画图操作。
A. start( ) B. stop( )
C. init( ) D. paint( )
下列哪个叙述是不正确的?( B )
A.JButton在javax.Swing包中
B.ActionEvcent在java.awt包中(其实在javax.Swing包中)
C.ActionListener在java.awt.event包中
D.Font类在java.awt包中
下列流中哪些不属于字节流(D)
A.FileInputStream B.BufferedInputStream C.FileInputStream D.InputStreamReader
下面哪一个import命令可以为我们提供编写网络应用程序的类(D
)
A、import java.sql.; B、import java.util.;
C、import java.io.; D、import java.net.;
如果需要从文件中读取数据,则可以在程序中创建哪一个类的对象(A)
A、FileInputStream B、FileOutputStream
C、DataOutputStream D、FileWriter
Java属于( A )型语言。
A.解释 B.编译 C.多线程性 D.安全性
下列说法中,错误的一项是( D
)
A.在Java中,若要处理某类事件,必须定义相关的事件处理类
B.在对事件源实例化之后,要注册相应事件的监听器
C.事件处理类必须实现与该类事件相对应的监听器接口
D.事件源通常是一个构件,也称做监听器
下列哪项是不能改变线程状态的方法?(C )
A.start( ) B.sleep( ) C.main( ) D.stop( )
下面语句的功能是( A)。
RandomAccessFile raf2 = new RandomAccessFile("1.txt","rw" );
A)打开当前目录下的文件1.txt,既可以向文件写数据,也可以从文件读数据。
B)打开当前目录下的文件1.txt,但只能向文件写入数据,不能从文件读取数据。
C)打开当前目录下的文件1.txt,但不能向文件写入数据,只能从文件读取数据。
D) 以上说法都不对。
应用程序的main方法中有以下语句,则输出的结果是 B( )。
String s="12345#aaa#bbb#67890";
int n=s.indexOf("#");
int k=s.indexOf("#",n+1);
int m=s.indexOf("#",k+1);
String s2=s.substring(m+1);
System.out.println(s2);
A) 123456 B) 67890 C) aaa D) bbb
下面程序段执行后b的值是(B )。
Integer integ =new Integer(9);
boolean b = integ instanceof Object;
A) 9 B) true C) 1 D) false
应用程序Test.java的源程序如下,在命令行键入:
java Test aaa bb c
回车后输出的结果是 ( A )。
public class Test {
public static void main(String args[]) {
int k1=args.length;
int k2=args[1].length();
System.out.print(k1+" "+k2);
}
}
//args.length表示传入参数的个数
A) 3 2 B)1 2 C) 1 3 D) 3 3
当某一线程正处于休眠状态,而另一个线程用 Thread 类中的 interrupt() 方法中断它时,抛出的异常类型是( C )。
A) IOException B) RuntimeException
C) InterruptedException D) ClassNotFoundException
以下关于java异常说法不正确的是(D )。
A) Throwable 类是 Java 语言中Error类和Exception类的父类。
B)当异常对象是Exception类(或其子类)的实例时,能通过 Java 虚拟机或者 throw 语句抛出该异常对象,并能通过try…catch…finally处理。
C)如果只用一个catch块捕捉多个异常对象,则catch 子句中的参数类型应是所有异常对象的父类。
D)以上说法都不对。
下面说法不正确的是( D )?
A)列表(List)、集合(Set)和映射(Map)都是java.util包中的接口。
B)List接口是可以包含重复元素的有序集合。
C)Set接口是不包含重复元素的集合。
D)Map接口将键映射到值,键可以重复,但每个键最多只能映射一个值。
Frame对象默认的布局管理器是(B )。
A、FlowLayout B、BorderLayout
C、CardLayout D、null
关于对象成员占用内存的说法哪个正确? ( B )
A.同一个类的对象共用同一段内存
B、同一个类的对象使用不同的内存段,但静态成员共享相同的内存空间
C.对象的方法不占用内存
D.以上都不对
下列说法哪个正确? ( A )
A、一个程序可以包含多个源文件
B、一个源文件中只能有一个类
C、一个源文件中可以有多个公共类
D、一个源文件只能供一个程序使用
构造函数何时被调用? ( A )
A、创建对象时 B、类定义时
C、使用对象的方法时 D、使用对象的属性时
覆盖与重载的关系是 ( A )
A、覆盖只有发生在父类与子类之间,而重载可以发生在同一个类中
B.覆盖方法可以不同名,而重载方法必须同名
C.final修饰的方法可以被覆盖,但不能被重载
D.覆盖与重载是同一回事
关于接口哪个正确? ( A )
A、实现一个接口必须实现接口的所有方法
B.一个类只能实现一个接口
C.接口间不能有继承关系
D.接口和抽象类是同一回事
异常包含下列哪些内容? ( A )
A.程序执行过程中遇到的事先没有预料到的情况
B.程序中的语法错误
C.程序的编译错误
D.以上都是
下列流中哪个不属于字节流 (D)
A.FileInputStream
B.BufferedInputStream
C. FilterInputStream
D. InputStreamReader
5<<1的结果为(C)
C.10
以下哪个方法用于定义线程的执行体? ( C )
A、 start() B、init() C、run() D、synchronized()
下面哪个不是Java中的容器? ( B )
A、 ScrollPane B、Canvas C、Applet D、Dialog
下面哪个方法与applet的显示无关?( A )
A、draw() B、 update() C、repaint() D、paint()
当Frame改变大小时,放在其中的按钮大小不变,则使用如下哪种布局方式? ( A )
A、 FlowLayout B、CardLayout C、BorderLayout D、GridLayout
给出如下代码:
class Test{ private int m;
public static void fun() { // some code… } }
如何使成员变量m 被函数fun()直接访问?( C )
A、将private int m 改为protected int m B、将private int m 改为 public int m
C、将private int m 改为 static int m D、将private int m 改为 int m
写出以下程序的运行结果。 int
(类型转换,char -> int)
class OverloadDemo{
void testOverload( int i ){ System.out.println(“int”); }
void testOverload(String s){ System.out.println(“String”); }
public static void main(String args[ ]){
OverloadDemo a=new OverloadDemo ( );
char ch=’x’;
a.testOverload(ch); } }
编译并运行以下程序,以下描述哪个选项是正确的( C )。
class A{
protected String toString(){
return super.toString();}
}
A、编译通过运行无异常 B、编译通过但运行时出错 C、行2出错,不能成功编译 D、不能成功编译,行3出错
当用new运算符和构造方法创建对象时,下列哪个步骤的叙述是正确的?(1.0分)
-
A、
[1.为成员变量分配内存,并指定默认值。 2.初始化成员变量,即用户声明成员变量时给定的默认值。 3.执行构造方法。 4.计算出一个引用值。]
-
B、
[1.计算出一个引用值。 2.为成员变量分配内存,并指定默认值。 3.初始化成员变量,即用户声明成员变量时给定的默认值。 4.执行构造方法.]
-
C、
[1.为成员变量分配内存,并指定默认值。 2.初始化成员变量,即用户声明成员变量时给定的默认值。 3.计算出一个引用值。 4.执行构造方法]
-
D、
[1.执行构造方法。 2.为成员变量分配内存,并指定默认值。 3.初始化成员变量,即用户声明成员变量时给定的默认值。 4.计算出一个引用值。]
正确答案: A
填空题
Java语言采用多种机制来保证可移植性,其中最主要的是___java虚拟机___。
当联编推迟至运行时间实现时,该联编过程称为_动态联编_____。
使用默认字节字符对应表,将字符串转化为字节数组的方法是___getBytes();。
Java程序可以用纯Java的___JDBC_____驱动程序,实现与数据库连接。
在多线程系统中,多个线程之间有 ( 同步 ) 和 ( 互斥 ) 两种关系。
程序中实现多线程的方法有两种:继承Thread类和实现( Runnable )接口。
同一个类中多个方法具有相同的方法名,不同的参数列表称为方法的( 重载 )。
在Java的基本数据类型中,char型采用Unicode编码方案,这样无论是中文字符还是英文字符,都是占用( 2 )字节内存空间
开发与运行Java程序需要经过的三个主要步骤为 编辑源程序 、 编译生成字节码
和 解释运行字节码 。
用户自定义异常是通过继承_____ 异常 ____类或其子类。
_OutputStreamWriter__类是OutputStream类的子类,用来处理以文件作为数据输出的数据流。
Socket通常也称为 ( 套接字 ),用于描述( IP地址 ) 和 ( 端口 )。
线程的优先级在( 1 )至( 10 )之间,数值越大( 任务越紧急 )。
在一个时间只能由一个线程访问的资源称为 ( 临界资源 ) 。访问临界资源的代码( 临界代码 )
在多线程系统中,多个线程之间有 ( 同步 ) 和 ( 互斥 ) 两种关系。
简答题
1、什么是访问权限?每种访问权限各有什么作用?
访问权限是在类的定义中使用权限修饰符实现的,已达到保护类的变量和方法的目的。
private: 私有的,被其修饰的属性以及方法只能被该类的对象访问,其子类不能访问,不允许跨包访问。
default:默认访问权限,即不加任何访问修饰符,只允许在当前类和同一个包中进行访问。
protected: 保护访问权限,被其修饰的属性以及方法只能被类本身的方法及子类访问,即使子类在不同的包中也可以访问。
public: 公共访问权限,被其修饰的类、属性以及方法不仅可以跨类访问,而且允许跨包访问。
2、什么是构造方法?什么时候使用构造方法?
构造方法是一个与类同名且没有返回值类型的方法,其功能主要是完成对象的初始化。
当类实例化一个对象时会自动调用构造方法。
3、什么是 Java 的继承机制?
子类继承了父类,拥有了父类的属性和方法。Java中的继承是单继承,只能继承一个父类。
子类可以修改父类的状态或重写父类的行为,为自身添加新的状态和行为。
4、面向对象语言有哪三个特点?
继承,封装,多态
5、throws 和 throw 有什么区别?
throws 方法声明时使用,表示该方法可能产生的异常,抛出,谁调用谁捕获处理,throws用在函数上。
throw方法体中使用,表示抛出一个具体的异常对象,谁调用谁捕获处理,throw用在函数内。
6、类变量与实例变量有什么区别?
类变量在变量前加static,实例变量没加。
类变量是所有对象共有,其中一个对象将它值改变,其他对象得到的就是改变后的结果。而实例变量则属对象私有,某一个对象将其值改变,不影响其他对象
7、Java 八种基本类型所对应的包装类是什么?
byte – Byte
short – Short
int – Integer
long – Long
float – Float
double – Double
char – Character
boolean – Boolean
8、什么是自动装箱?什么是自动拆箱?
定义:基本数据类型和包装类之间可以自动地相互转换
理解:装箱就是自动将基本数据类型转换为封装类型,拆箱就是自动将封装类型转换为基本数据类型。
9、使用输入流的基本步骤是什么?
10、使用输出流的基本步骤是什么?
11、建立线程有几种方法?
第一种是继承Thread类,重写run() 方法
第二种是实现 Runnable接口,实现run()方法
12、简述 try-catch-finally 语句块的作用。
首先执行可能发生异常的try语句块,如果try语句没有出现运行时异常则执行完后跳至finally语句块执行;如果try语句出现异常,则中断执行并根据发生的异常类型跳至相应的catch语句块执行处理。catch语句块执行完后程序会继续执行finally语句块。finally语句是可选的,如果有的话,则不管是否发生异常,finally语句都会被执行。
try-catch-finally 保证Java程序正常安全的运行,增强了程序的错误检测和处理能力,提高了程序的可靠性。
13、方法重写和方法重载有什么区别?
重载:当前类中方法名相同,参数的个数或者类型不同
重写:发生在子类中,子类的方法与父类方法名、参数个数、参数类型,返回值类型完全相同,并且访问权限不能高于父类
14、在多线程中,为什么要引入同步机制?
同步机制防止多线程冲突,防止数据混乱
15、什么是线程同步?
在Java多线程机制中,提供了关键词synchronized来实现线程间的同步。
线程同步是表明该对象在任一时刻只能由一个线程访问,在该线程完成任务之前,不会被其他线程访问修改。
16、Java 基本类型有哪些?
- 整型:byte、short、int、long
- 浮点型:float、double
- 字符型:char
- 布尔类型:boolean
17、什么是进程?什么是线程?线程与进程有什么区别?
进程就是一个执行的程序,线程是一个程序中的单个执行流。
进程是由线程所组成的,一个程序至少有一个进程,一个进程至少有一个线程。
每一个进程都占有独立的地址空间,而一个进程中的多个线程可共享该进程的这些空间。
18、抽象类与接口有什么区别?
-
抽象类只能单继承,接口可以被多实现。
-
接口只有定义,不能有方法的实现,而抽象类可以有定义与方法实现。
-
抽象类的成员修饰符可以自定义,接口中的成员修饰符全都是public的。
-
实现接口的关键字为implements,继承抽象类的关键字为extends。
-
抽象类可以有构造方法,接口中不能有构造方法
-
抽象类中可以有普通成员变量,接口中没有普通成员变量
19、Java 程序的开发步骤是什么?
编写源程序,编译生成字节码,解释运行字节码
20、子类重写方法的规则是什么?重写方法的目的是什么?
方法的返回值,方法名,方法参数必须和父类相同,访问权限不能低于父类,如果在父类中该方法抛出异常,则在子类重写时抛出异常不能高于父类或者不抛异常。
它的目的是改变父类的行为,子类中的新方法将覆盖原有的方法,增强类的重用性、复用性以及扩展性。
程序设计题
1、按以下要求编写程序
(1) 创建一个Rectangle类,添加width和height两个成员变量
(2) 在Rectangle中添加两种方法分别计算矩形的周长和面积
(3) 编程利用Rectangle输出一个矩形的周长和面积
解答:
public class Rectangle {
float width, height;
public Rectangle(float width, float height) {
this.width = width;
this.height = height;
}
public float getLength(){
return (this.width + this.height) * 2;
}
public float getArea(){
return this.width * this.height;
}
public static void main(String [] args) {
Rectangle rect = new Rectangle(10, 20);
System.out.println("周长是:" + rect.getLength());
System.out.println("面积是:" + rect.getArea());
}
}
2、按以下要求编写程序
(1) 编写Animal接口,接口中声明run() 方法
(2) 定义Bird类和Fish类实现Animal接口
(3) 编写Bird类和Fish类的测试程序,并调用其中的run()方法
解答:
public interface Animal {
void run();
}
class Bird implements Animal {
public void run() {
System.out.println("鸟儿在飞...");
}
}
class Fish implements Animal {
public void run() {
System.out.println("鱼儿在游...");
}
}
public class TestAnimal {
public static void main(String[] args) {
Bird bird = new Bird();
bird.run();
Fish fish = new Fish();
fish.run();
}
}
3.编写一个完整的JavaApplication程序。
包含接口ShapeArea,类Circle、Rectangle、Test,具体要求如下:
⑴接口ShapeArea:①接口方法 doublegetArea():求一个形状的面积 doublegetPerimeter():求一个形状的周长
⑵类Rectangle:实现ShapeArea接口,并有以下属性和方法: ① 属性 width:double型,表示长方形的宽度 height:double型,表示长方形的长度 ②方法 Rectangle(doublew,doubleh):构造函数 toString():输出矩形的描述信息,如“width=1.0,height=2.0,perimeter=6.0,area=2.0”
⑶Test类作为主类要完成测试功能 ① 生成Rectangle对象 ②调用对象的toString方法,输出对象的描述信息
public classTest{//主类定义2分
public static void main(String args[]){
Rectangler=new Rectangle(1,2);
System.out.println(r.toString());
} }
interface ShapeArea//接口定义2分
{
public abstract double getPerimeter();
public abstract double getArea(); }
class Rectangle implements ShapeArea{
double width,height;//属性定义1分
Rectangle(doublew,doubleh) //构造函数定义1分
{ width=w;height=h; }
public double getPerimeter()//1分
{return 2*(width+height);}
public double getArea()//1分
{return width*height;}
public String toString()//2分
{ return"width="+width+",height="+height+",perimeter="+getPerimeter()+",area="+getArea();
} }