java笔记-做题点II

java专项练习模糊点第二弹。
包括异常的捕获与处理、Hashtable和HashMap、数组的创建等。


1.关于异常的编程:

异常分为运行时异常,非运行时异常和error。其中error是系统异常,只能重启系统解决;非运行时异常需要我们自己补获;而运行异常是程序运行时由虚拟机帮助我们补获,运行时异常包括数组的溢出,内存的溢出空指针,分母为0等;
输入输出流编程中,读和写时都要抛出IOException;
int a[]=null; a[0]=1; 将产生NullPointerException;
在某些接口实现中我们通常需要捕获编译运行期所有的异常,用catch下Exception的实例进行捕获,因为catch下的error是系统出错,catch是无法处理的,难以修复的,RuntimeException不需要程序员进行捕获处理,error和exception都是throwable的子类。

2.非静态变量不能够被静态方法引用。

3.Hashtable和HashMap:

(1)继承不同,但是都实现了Map接口。
public class Hashtable extends Dictionary implements Map
public class HashMap extends AbstractMap implements Map
(2)Hashtable 中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。在多线程并发的环境下,可以直接使用Hashtable,但是要使用HashMap的话就要自己增加同步处理了。
(3)Hashtable中,key和value都不允许出现null值;
在HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,即可以表示 HashMap中没有该键,也可以表示该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键, 而应该用containsKey()方法来判断。
(4)两个遍历方式的内部实现上不同。
Hashtable、HashMap都使用了 Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。
(5)哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。
(6)Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。
HashTable中hash数组默认大小是11,增加的方式是 old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。

4.关于数组的创建:

float f[][] = new float[6][6];
float []f[] = new float[6][6];
float [][]f = new float[6][6];
float [][]f = new float[6][];
以上均可,但是下面这种不可以:float f[][] = new float[][6];

即数组命名时名称与[]可以随意排列,但声明的二维数组中第一个中括号中必须要有值,它代表的是在该二维数组中有多少个一维数组。

5.重写时候,子类方法的权限要大于等于父类方法的权限。

6.一道题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class NameList
{
private List names = new ArrayList();
public synchronized void add(String name)
{
names.add(name);
}
public synchronized void printAll() {
for (int i = 0; i < names.size(); i++)
{
System.out.print(names.get(i) + ””);
}
}
public static void main(String[]args)
{
final NameList sl = new NameList();
for (int i = 0; i < 2; i++)
{
new Thread()
{
public void run()
{
sl.add(“A”);
sl.add(“B”);
sl.add(“C”);
sl.printAll();
}
} .start();
}
}
}
Which two statements are true if this class is compiled and run?

answer:
The code may rum with output “A B C A B C A B C “, then exit.
The code may ruin with output “A B C A A B C A B C “, then exit.

【解释也没看懂……之后自己再回来看这个吧】

7.关于java异常处理:

throws用于在方法上声明该方法不需要处理的异常类型,用在方法上后面跟异常类名 可以是多个异常类;
throw用于抛出具体异常类的对象,用在方法内,后面跟异常对象只能是一个异常类型实体。
try块必须和catch块或和finally同在,不能单独存在,二者必须出现一个。
finally块总会执行,不论是否有错误出现。但是若try语句块或会执行的catch语句块使用了JVM系统退出语句,finally块就不会被执行了。一般我们把关闭资源的代码放在finally里面,保证资源总是能关闭。

try没执行,所以没有异常抛出,程序继续,finally必须执行,try外部代码执行;
try执行,抛出异常,程序中断,执行catch,最后执行finally,程序结束;
即无论有没有异常,finally块中的代码都会执行。

假设利用return语句从try语句块中退出。在方法返回前,finally子句的内容将被执行。如果finally子句中也有一个return语句,这个返回值将会覆盖原始的返回值。
如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static void main(String[] args) {
int k = f_test();
System.out.println(k);
}
public static int f_test(){
int a = 0;
try{
a = 1;
return a;
}
finally{
System.out.println("It is in final chunk.");
a = 2;
return a;
}
}

会输出:
It is in final chunk.
2

如果注释掉finally里的return a;
则输出:
It is in final chunk.
1

即finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,不管finally中的代码怎么样,返回的值都不会改变,仍然是之前保存的值),所以函数返回值是在finally执行前确定的;

finally语句块在catch语句块中的return语句之前执行;

所以finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。

在try语句块或catch语句块中执行到System.exit(0)直接退出程序。