2021年09月23日 java1
考点1:this调用语句
This调用语句必须是构造函数中的第一个可执行语句。
- A 正确
- B 错误
显示答案/隐藏答案
正确答案: Bthis()才必须是构造函数中的第一个可执行语句,用this调用语句并不需要。
考点2:成员内部类
内部类(也叫成员内部类)可以有4种访问权限。( )
- A 正确
- B 错误
显示答案/隐藏答案
正确答案: A你就把内部类理解成类的成员,成员有4种访问权限吧,内部类也是!分别为private、protected、public以及默认的访问权限
考点3:CallableStatement PreparedStatement Statement
以下描述正确的是
- A CallableStatement是PreparedStatement的父接口
- B PreparedStatement是CallableStatement的父接口
- C CallableStatement是Statement的父接口
- D PreparedStatement是Statement的父接口
显示答案/隐藏答案
正确答案: BStatement 每次执行sql语句,数据库都要执行sql语句的编译 ,最好用于仅执行一次查询并返回结果的情形,效率高于PreparedStatement.
PreparedStatement是预编译的,使用PreparedStatement有几个好处
a. 在执行可变参数的一条SQL时,PreparedStatement比Statement的效率高,因为DBMS预编译一条SQL当然会比多次编译一条SQL的效率要高。
b. 安全性好,有效防止Sql注入等问题。
c. 对于多次重复执行的语句,使用PreparedStament效率会更高一点,并且在这种情况下也比较适合使用batch;
d. 代码的可读性和可维护性。
CallableStatement接口扩展PreparedStatement,用来调用存储过程,它提供了对输出和输入/输出参数的支持。CallableStatement
接口还具有对 PreparedStatement 接口提供的输入参数的支持。
1 | public interface CallableStatement |
1 | public interface PreparedStatement |
1 | public interface Statement |
考点4:多态方法调用
Test.main()函数执行后的输出是( )
1 | class Test { |
- A 6 7 7
- B 22 34 17
- C 22 74 74
- D 11 17 34
显示答案/隐藏答案
正确答案: B始终优先调用子类重写的方法
本题中,始终需要遵循一个原则,即: 调用的方法都是实例化的子类中的重写方法,只有明确调用了super.xxx关键词或者是子类中没有该方法时,才会去调用父类相同的同名方法。
这道题的知识点:子类中的方法覆盖父类的方法以后,由于向上转型,父类调用方法的时候是调用子类的,除非用super。
还有一个点就是在Try catch finally 体系当中,在return之前始终会执行finally里面的代码,如果finally里面有return,则数据跟随finally改变。如果没有return,则原数据不跟随finally里改变的数据改变!
main方法中只有一条System.out.println(new B().getValue());语句
先执行new B()
new B()
B类
1
2
3
4 public B () {
super(5);//<--执行这句
setValue(getValue()- 3);
}super(5);
A类
1
2
3 public A (int v) { //v=5
setValue(v);//v=5
}因为new的对象是B,执行的是子类重写的setValue():
B类
1
2
3 public void setValue(int value) {//v=5
super.setValue(2 * value);//2*value=2*5=10
}这里明确使用了super关键字,所以调用父类的setValue方法:
A类
1
2
3 public void setValue(int value) {//value=10
this.value= value;//value=10,this.value=10
}到这里super(5);算是执行完毕了,继续执行下一句:
B类
1
2
3
4 public B () {
super(5);//<--执行完毕
setValue(getValue()- 3);//<--执行
}执行 setValue(getValue()- 3);
先执行getValue()方法,B类中并没有有定义getValue()方法,所以调用的是父类的getValue方法:
先执行getValue的try语句块
public int getValue() { try { value ++;//1. value=10,value++之后value=11 return value;//2 return 11; } finally { this.setValue(value); //3. 当前对象是B类的对象,调用B类的setValue方法,value=11 System.out.println(value); } }
try块中有return语句,getValue的返回值为11
然后执行finally语句块。
先执行this.setValue(value);
public void setValue(int value) {// value=11 super.setValue(2 * value);//2 * value=2 *11=22,接着调用父类的setValue方法 }
调用父类的setValue方法
public void setValue(int value) {// value=22 this.value= value;//this.value=22 }
然后执行System.out.println(value);输出22
getValue()执行完毕,返回值11
1
2
3
4 public B () {
super(5);
setValue(getValue()- 3);//getValue=11,getValue()- 3=11-3=8
}执行setValue(8),当前对象有setValue方法,调用B类定义的setValue方法:
1
2
3 public void setValue(int value) {//value=8
super.setValue(2 * value);//2 * value=2*8=16
}执行父类的setValue方法:
public void setValue(int value) {//value=16 this.value= value;//this.value=16 }
到这里,new B()执行完毕。this.value=16
然后执行new B().getValue()
然后执行new B().getValue()
子类B中没有这个方法,调用父类继承来的getValue方法先执行try块:
1
2
3
4
5
6
7
8
9 public int getValue() {
try {
value ++;//this.value=16 value++之后 this.value=17
return value;//getValue()返回值是17
} finally {
this.setValue(value);
System.out.println(value);
}
}然后执行finally块:
1
2
3
4
5
6
7
8
9 public int getValue() {
try {
value ++;//this.value=17
return value;//getValue()返回值是17
} finally {
this.setValue(value);//value=17
System.out.println(value);
}
}先调用当前类的setValue方法:
1
2
3 public void setValue(int value) {//value=17
super.setValue(2 * value);//2 * value=2 * 14=34
}调用父类的setValue方法:
public void setValue(int value) {//value=24 this.value= value;//this.value=34 }
然后执行 System.out.println(value);语句,输出34
到这里new B().**getValue()**已经执行完毕,getValue()返回17.
最后执行最外层的数据语句
1
2
3 public static void main(String[] args) {
System.out.println(new B().getValue());//17
}输出17
考点5:JRE判断程序执行结束的标准 前台线程 后台线程
jre 判断程序是否执行结束的标准是()
- A 所有的前台线程执行完毕
- B 所有的后台线程执行完毕
- C 所有的线程执行完毕
- D 和以上都无关
显示答案/隐藏答案
正确答案: A前台线程 后台线程 用户线程 守护线程
其实这个题,就是在说守护线程和非守护(用户)线程的问题。后台线程就是守护线程,前台线程就是用户线程。
守护线程:是指在程序运行时在后台提供一种通用服务的线程,这种线程并不是必须的。同时守护线程的线程优先级都很低的。JVM中的GC线程就是一个守护线程,只要JVM启动,GC线程就启动了。
用户线程和守护线程几乎没有什么区别,唯一的区别就在于,如果用户线程都已经退出了,只剩下了守护线程,那么JVM直接就退出了。
下面举个例子:
1 | class ThreadDemo extends Thread { |
程序输出:
1 | test : begin |
运行结果中不会有Thread-0 : end,是因为,守护线程开启之后,中间睡了2s,这个时候又没有锁,主线程直接就执行完了,
一旦主线程结束,那么JVM中就只剩守护线程了,JVM直接就退出了,不管你守护线程有没有执行完。
jre判断程序是否执行结束的标准是:所有的前台线程执行完毕。
考点6:自增运算符
以下代码执行的结果显示是多少()?
1 | public class Demoe { |
- A num * count = 505000
- B num * count = 0
- C 运行时错误
- D num * count = 5050
显示答案/隐藏答案
正确答案: Bcount = count++;
这个先将count这个值0暂存起来,然后count自加1变成1,最后将暂存的值赋值给count,count最终的值为0
考点7:类的加载顺序:先静态后非静态 先父类后子类
关于下列代码的执行顺序,下面描述正确的有哪些选项()
1 | public class HelloA { |
- A 打印顺序A的静态代码块> A的构造函数
- B 打印顺序A的静态代码块> A的构造代码块
- C 打印顺序A的构造代码块> A的构造函数
- D 打印顺序A的构造函数> A的构造代码块
显示答案/隐藏答案
正确答案: ABC类的加载顺序
1.父类静态代码块
2.子类静态代码块
3.父类构造代码块
4.父类构造函数
5.子类构造代码块
6.子类构造方法
总结:先静态后非静态,先父类后子类。
考点8:字符集编码 国际化
在Java语言中,下列关于字符集编码(Character set encoding)和国际化(i18n)的问题,哪些是正确的?
- A 每个中文字符占用2个字节,每个英文字符占用1个字节
- B 假设数据库中的字符是以GBK编码的,那么显示数据库数据的网页也必须是GBK编码的。
- C Java的char类型,通常以UTF-16 Big Endian的方式保存一个字符。
- D 实现国际化应用常用的手段是利用ResourceBundle类
显示答案/隐藏答案
正确答案: CD解析
A 显然是错误的,Java一律采用Unicode编码方式,每个字符无论中文还是英文字符都占用2个字节。
B 也是不正确的,不同的编码之间是可以转换的,通常流程如下:
将字符串S以其自身编码方式分解为字节数组,再将字节数组以你想要输出的编码方式重新编码为字符串。
例:
GBK字符串转UTF-8字符串
1 | String newUTF8Str = new String(oldGBKStr.getBytes("GBK"), "UTF8"); |
C 是正确的。Java虚拟机中通常使用UTF-16的方式保存一个字符
D 也是正确的。ResourceBundle能够依据Local的不同,选择性的读取与Local对应后缀的properties文件,以达到国际化的目的。
综上所述,答案是 C 和 D。
考点9:字符流 字节流
character流和byte流的区别不包括()
- A 每次读入的字节数不同
- B 前者带有缓冲,后者没有。
- C 前者是字符读入,后者是字节读入。
- D 二者没有区别,可以互换。
显示答案/隐藏答案
正确答案: ABD字符流和字节流每次读入的字节数是不确定的,可能相同也可能不相同;
字符流和字节流都有缓冲流