(1)
synchronized 关键字 : 用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这个段代码。
volatile:用来确保将变量的跟新操作通知到其他线程,当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作一起重排序。然而,在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比 synchronized关键字更轻量级的同步机制。
serialize:Java 对象序列化为二进制文件。
static关键字: static关键字可以修饰变量,方法,静态代码块。
静态变量:
由static修饰的变量称为静态变量
静态变量属于类,而不属于某个对象
静态变量它的副本只有一个(静态变量在类中只加载一)
静态方法:
在静态方法中只能调用静态变量和静态方法
在非静态方法中,可以调用静态方法或者变量。
在静态方法中不能使用this和super关键字。
静态代码块
作用:用来给静态成员变量初始化
(2)写出下面代码的输出结果是什么 结果是 1234
public
class
Test
{
public
static
void
changeStr(String str)
{
str =
"welcome"
;
}
public
static
void
main(String[] args)
{
String str =
"1234"
;
changeStr(str);
System.out.println(str);
}
}
解析:
此处应该考察Java方法参数传递特性。Java方法调用中,只存在值传递调用。
此处,实参str是引用变量,由于java方法调用是值传递,所以形参str得到的是实参str的一个拷贝。此时形参str和实参str均指向字符串"1234"。
然后,在changeStr方法中,形参str指向了一个新的字符串"welcom",而后方法结束,形参str被销毁。而实参str仍然指向字符串"1234"。
(3)
数组初始化有三种方式:
- 动态初始化:数组定义与为数组分配空间和赋值的操作分开进行;
- 静态初始化:在定义数字的同时就为数组元素分配空间并赋值;
- 默认初始化:数组是引用类型,它的元素相当于类的成员变量,因此数组分配空间后,每个元素也被按照成员变量的规则被隐式初始化。
public
class
Test {
public
static
void
main(String[] args) {
//动态初始化
int
[] a;
//int a[];两者都可以
a =
new
int
[
10
];
a[
0
] =
0
;
a[
1
] =
1
;
a[
2
] =
2
;
//静态初始化
int
[] b = {
0
,
1
,
2
};
//int b[] = {0, 1, 2};两者都可以
//默认初始化
int
[] c =
new
int
[
10
];
//int c[] = new int[10];两者都可以
}
}
(4)
Test.main() 函数执行后的输出是 22
,
34
,
17
- public class Test {
- public static void main(String [] args){
- System.out.println(new B().getValue());
- }
- static class A{
- protected int value;
- public A(int v) {
- setValue(v);
- }
- public void setValue(int value){
- this.value = value;
- }
- public int getValue(){
- try{
- value++;
- return value;
- } catch(Exception e){
- System.out.println(e.toString());
- } finally {
- this.setValue(value);
- System.out.println(value);
- }
- return value;
- }
- }
- static class B extends A{
- public B() {
- super(5);
- setValue(getValue() - 3);
- }
- public void setValue(int value){
- super.setValue(2 * value);
- }
- }
- }
解析:
首先,super()函数指的是调用父类的构造方法
①
new B()
执行B的构造函数,第一行是super(5);
此时执行的是A的构造函数,A的构造函数调用的是setValue()方法,由于B重写了A的这个方法,
所以!!!执行的是B的 setValue()方法。
即传入的参数是2*5=10
此时,因为super,所以调用的是父类的 setValue()方法,即value=10
第一行执行完毕。
第二行是 setValue(getValue()-3);
B没有getValue()方法,故执行父类的此方法,
try返回的是value=10+1=11,保存在临时栈中
finally中调用this的方法,这个this指的是B的对象,又重写,故就是B的 setValue()方法
value=2*11=22,第一个打印到屏幕上的数字
接下来参数 getValue()-3=11-3=8
传入B的 setValue()方法
此时value=2*8=16
至此,new B()执行结束
②
new B(). getValue()
B没有 getValue(),故执行A的 getValue()
try返回16+1=17,保存到临时栈中
finally调用B的 setValue()方法
value=17*2=34,第二个打印到屏幕上面的数字
最后主函数打印返回值,也就是try保存到临时栈的17
(5)有关 JAVA 异常类的描述
都是Throwable的子类:
1.Exception(异常) :是程序本身可以处理的异常。
2.Error(错误): 是程序无法处理的错误。这些错误表示故障发生于虚拟机自身、或者发生在虚拟机试图执行应用时,一般不需要程序处理。
3.检查异常(编译器要求必须处置的异常) : 除了Error,RuntimeException及其子类以外,其他的Exception类及其子类都属于可查异常。这种异常的特点是Java编译器会检查它,也就是说,当程序中可能出现这类异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。
4.非检查异常(编译器不要求处置的异常): 包括运行时异常(RuntimeException与其子类)和错误(Error)。
(6)Java的接口