北京理工大学2021-2022学年第二学期2020级面向对象技术与方法(Java语言)期末试题(A卷)
班级________ 学号________ 姓名________ 成绩________
一、填空题(每空1.5分,共15分)
- Java中的
垃圾回收机制一定程度上消除了程序中的内存泄露(memory leak)问题。 - 对方法使用修饰符
final意味着它不能被重载。 - 封装是指把数据成员和相关的方法都放进类中,并使用
访问修饰符来控制其可见性。 - 标准的
IO流包括System.in、System.out和System.err。 - 定义目录过滤器时需要重写
FilenameFilter中的accept方法。 - Java中的
RandomAccessFile类提供了随机访问文件的功能。 .this的含义是当前对象的引用。- 可以对象序列化的对象的所属类需要实现
Serializable接口。 - 使用关键字
package为当前java文件中的类指定所属的包。 - 子类重写父类的方法的时候,方法的访问权限必须
大于或等于父类的方法的访问权限。
二、判断正误(每题1分,共10分)
- “
float x1=1.414f;”语句中等号右边的f是多余的() - 数组有
length()方法。( ) - Java语言的跨平台性使得它不需要像C语言一样提供
sizeof运算符。( ) 内部类(inner class)可以访问其外部类(enclosing class)中的private成员。( )匿名类不一定是内部类( )- Java语言中不同数据类型的长度是固定的,不随机器硬件不同而改变。( )
- 对象中必须有属性和方法( )
- 类的
静态方法可以在该类的对象被创建前调用( ) - 同一个类的不同对象共用一个
this( ) - 当一个方法在运行过程中产生一个
异常,如果不及时捕获处理,这个方法会终止,但是整个程序不一定终止。( )。
三、单选题(每题2分,共20分)
- 下列( )是合法的标识符 A.
12classB.voidC.-5D._blank - 下列说法错误的是( ): A. 数组可以动态初始化; B. 数组可以赋值给
Object类型的对象; C. 数组创建以后,其长度可以修改; D. 数组可以调用Object类的所有方法; - 类
A有一个方法void method(),要求能够通过类名A直接调用method(),则方法定义应该为( ) A.static void method()B.public void method()C.final void method()D.abstract void method() - 下面关于Java的隐藏和覆盖的说法,正确的是( ) A. 覆盖方法时需要保证方法名完全相同 B. 覆盖方法时不需要参数列表完全相同 C. 覆盖方法时返回值的类型必须完全一样 D. 进行变量隐藏时不能够修改变量类型
- 类
A有a、b、c三个public变量成员,B类继承自A,并且增加了自己的public变量成员d,C继承自A,增加了自己的public变量成员e,则下列说法中错误的是( ) A.A类拥有c成员 B.B类拥有b成员 C.C类拥有d成员 D.B类拥有c成员 - 以下描述正确的是( ) A. 使用
FileOutputStream可以将对象进行传输 B. 使用PrintWriter可以将对象进行传输 C.static类型的数据成员不可以被序列化 D. 对象序列化时,所有的数据成员都必须被序列化 - 运行下面程序时,会产生什么异常?( )
public class X7_1_5 {
public static void main(String[] args) {
int[] z = {1,2,3,4};
int p = z[4];
int x = 0;
int y = 5/x;
}
}A. ArithmeticException B. NumberFormatException C. ArrayIndexOutOfBoundsException D. IOException 8. 下列选项中关于Java中super关键字的说法正确的是( )。 A. super关键字是在子类对象内部指代其父类对象的引用 B. super关键字不仅可以指代子类的直接父类,还可以指代父类的父类 C. 子类通过super关键字只能调用父类的方法,而不能调用父类的属性 D. 子类通过super关键字只能调用父类的属性,而不能调用父类的方法 9. 下列循环体执行的次数是( )。
int y=2, x=4;
while(--x != x/y){ }(A)1 (B)2 (C)3 (D)4 10. 下列语句中不正确的一个是( )。 (A)float f = 1.1f; (B)byte b = 128; (C)double d = 1.1/0.0; (D)char c = (char)1.1f;
四、简答题(共35分)
- 写出该程序的输出结果 (5分)
class Bowl {
Bowl(int marker) {
System.out.println("Bowl(" + marker + ")");
}
}
class Table {
static Bowl b1 = new Bowl(1);
Table() {
System.out.println("Table()");
}
Bowl b5 = new Bowl(5);
static Bowl b2 = new Bowl(2);
}
class Cupboard {
Bowl b3 = new Bowl(3);
static Bowl b4 = new Bowl(4);
Cupboard() {
System.out.println("Cupboard()");
}
}
public class StaticInitialization {
public static void main(String[] args) {
System.out.println(
"Creating new Cupboard() in main");
new Cupboard();
new Table();
}
static Table t2 = new Table();
static Cupboard t3 = new Cupboard();
}该程序的输出结果为: 2. test1()中调用Collection.sort()方法,通过定制排序比较两个Employee(先按age字段升序排序,若age字段相同则按salary字段升序排序,若二者都相同则按照默认顺序即可)。请用lambda表达式在横线处补齐代码。(5分)
public class Employee{
private int number;
private String name;
private int age;
private double salary;
public int getAge(){
return age;
}
public double getSalary(){
return salary;
}
public Employee( int number,String name,int age,double salary ){
this.number=number;
this.name=name;
this.age=age;
this.salary=salary;
}
}
public class TestLambda {
List<Employee> emps = Arrays.asList(new Employee(101, "张三", 18, 9999.99),
new Employee(102, "李四", 59, 6666.66),
new Employee(105, "田七", 38, 5555.55)
);
public void test1() {
Collections.sort(emps, );
System.out.println("emps = " + emps);
}
}- 使用
lambda表达式和目录名过滤器列出c:\test文件中的所有txt文件(5分) - 简述Java中
垃圾回收机制(5分) - 按注释完成程序(5分)
public class Leaf {
private int i = 0; //此属性值用于检验
Leaf increment( ){ //定义方法increment(),返回值是Leaf类的对象
i++;
return (1) ________ ; //将当前对象的地址作为返回值返回
}
void print( ) {
System.out.println(" i = " + i);
}
public static void main(String args[ ]){
Leaf x = (2) ________ ; //创建Leaf类的对象x
x.increment( ).increment( ).increment().print();
}//多次调用方法increment( ),返回的都是x的地址,i 值表示调用次数
}执行main函数,控制台的输出为 i = (3) ________ 6. 创建一个学生类(Student),并在该类中定义3个成员变量学生学号(id)、名称(name)以及年龄(age),使用单例模式实现仅能创建Student类的1个实例。(5分) 7. 设计一个泛型方法,该方法输入为一个数组,返回数组中的最大值,要求使用compareTo方法比较数组中元素大小。(5分)
五、编程题(共20分)
- 定义一个接口
ICompute含有一个方法int computer(int n, int m);设计四个类分别实现此接口,完成加减乘除运算;设计一个类UseCompute,类中含有方法:public void useCom(ICompute com, int one, int two),此方法能够用传递过来的对象调用computer方法完成运算,并输出运算的结果。(8分) a.txt文件中有一些数据,格式为
age=10,name=zhangsan
age=2001,name=lisi
age=1,name=wangwu
age=66,name=zhaoliu将文件中的所有信息,通过合适的IO流读取出来,封装成Person对象,使用List集合进行存储;将集合对象序列化到另外一个文件persons.txt中;从persons.txt反序列化其中的集合,并遍历集合内容(12分)
答案与解析
(一)填空题
垃圾回收(Garbage Collection):Java的垃圾回收机制会自动回收不再被引用的对象所占用的内存,从而减少内存泄露问题。final:被final修饰的方法不能被重写(重载是指方法名相同,参数列表不同;重写是指子类重新实现父类的方法)。访问修饰符(如private、protected、public等):通过这些修饰符来控制类中成员的可见性,实现封装。System.err:标准的IO流中,System.in是标准输入流,System.out是标准输出流,System.err是标准错误输出流。accept:在定义目录过滤器时,需要重写FilenameFilter接口中的accept方法来指定过滤规则。RandomAccessFile:该类提供了对文件的随机访问功能,可以在文件的任意位置进行读写操作。当前对象的引用:在类的方法中,this代表调用该方法的当前对象。Serializable:一个类实现Serializable接口后,其对象才能被序列化,即转换为字节流进行存储或传输。package:使用package关键字为当前Java文件中的类指定所属的包,便于组织和管理类。大于:子类重写父类方法时,方法的访问权限必须大于或等于父类方法的访问权限,以保证多态性的正常运行。
(二)判断正误
- 错误:在Java中,
1.414是double类型常量,若要赋值给float类型变量,需加上后缀f,否则会报错。 - 错误:数组有
length属性,用于获取数组的长度,而不是length()方法。 - 正确:Java语言跨平台,其数据类型的长度是固定的,不依赖于具体的机器硬件,所以不需要
sizeof运算符来获取数据类型的大小。 - 正确:
内部类可以访问其外部类的所有成员,包括private成员。 - 错误:
匿名类一定是内部类,它是没有名字的内部类,通常用于创建只使用一次的类对象。 - 正确:Java中数据类型的长度是固定的,不随机器硬件不同而改变,保证了代码的可移植性。
- 错误:对象不一定必须有属性和方法,例如可以定义一个空类,它的对象就没有属性和方法。
- 正确:类的
静态方法属于类本身,而不是类的某个对象,所以可以在对象创建前调用。 - 错误:每个对象都有自己独立的
this引用,指向自身。 - 正确:当一个方法抛出
异常且未被捕获时,该方法会终止执行,但如果异常没有向上传播到整个程序的顶层,程序不会终止。
(三)单选题
- D:标识符不能以数字开头,不能是关键字(如
void),也不能包含特殊符号(如-),_blank符合标识符命名规则。 - C:数组创建后,其长度是固定的,不能修改。数组可以动态初始化,也可以赋值给
Object类型的对象,并且可以调用Object类的所有方法。 - A:要通过类名直接调用方法,该方法必须是
静态方法,用static修饰。 - A:覆盖方法时,方法名、参数列表和返回值类型都必须相同(在Java 5.0及以上版本,返回值类型可以是协变的,即子类方法的返回值类型是父类方法返回值类型的子类);变量隐藏时可以修改变量类型。
- C:
C类继承自A类,没有继承B类的d成员,A类拥有c成员,B类继承自A类,拥有b和c成员。 - C:
FileOutputStream和PrintWriter都不能直接传输对象;static类型的数据成员不可以被序列化;对象序列化时,用transient修饰的数据成员不会被序列化。 - C:程序中数组
z的下标最大为3,访问z[4]会导致ArrayIndexOutOfBoundsException异常;在抛出该异常后,后面的代码不会执行,所以不会出现ArithmeticException异常。 - A:
super关键字在子类对象内部指代其父类对象的引用,只能指代直接父类,既可以调用父类的方法,也可以调用父类的属性。 - B:第一次循环,
x初始值为4,--x后x为3,x/y为1,条件成立;第二次循环,--x后x为2,x/y为1,条件成立;第三次循环,--x后x为1,x/y为0,条件不成立,循环结束,所以循环体执行了2次。 - B:
byte类型的取值范围是-128到127,128超出了其取值范围,会报错。
(四)简答题
- 输出结果:
Bowl(1)
Bowl(2)
Bowl(4)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
Bowl(5)
Table()解析:在程序运行时,首先会加载静态成员。Table类的静态成员b1和b2会被初始化,执行Bowl的构造方法输出Bowl(1)和Bowl(2);Cupboard类的静态成员b4会被初始化,执行Bowl的构造方法输出Bowl(4)。然后执行main方法,创建Cupboard对象,初始化b3,输出Bowl(3),执行Cupboard的构造方法输出Cupboard();接着创建Table对象,初始化b5,输出Bowl(5),执行Table的构造方法输出Table()。 2. lambda表达式代码:
(emp1, emp2) -> {
if (emp1.getAge() != emp2.getAge()) {
return Integer.compare(emp1.getAge(), emp2.getAge());
} else {
return Double.compare(emp1.getSalary(), emp2.getSalary());
}
}解析:通过lambda表达式实现Comparator接口,先比较age字段,若相等再比较salary字段。 3. 列出.txt文件代码:
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class ListTxtFiles {
public static void main(String[] args) {
File testDir = new File("c:\\test");
List<File> txtFiles = Arrays.stream(testDir.listFiles((dir, name) -> name.endsWith(".txt")))
.collect(Collectors.toList());
txtFiles.forEach(System.out::println);
}
}解析:使用File类的listFiles方法结合lambda表达式作为目录过滤器,筛选出以.txt结尾的文件,并将结果收集到List中输出。 4. 垃圾回收机制简述:Java的垃圾回收机制是一种自动内存管理机制。它负责监测不再被程序使用的对象(即没有任何引用指向的对象),并回收这些对象所占用的内存空间。垃圾回收器在后台运行,不定时地进行垃圾回收操作。当一个对象不再被任何变量引用时,它就会被标记为可回收对象,垃圾回收器会在合适的时机释放这些对象占用的内存,从而避免内存泄露,提高内存的利用率。垃圾回收的算法有多种,如标记-清除算法、复制算法、标记-整理算法等,不同的JVM可能采用不同的算法或算法组合。 5. 程序填空答案: (1) this (2) new Leaf() (3) 3