Skip to content

北京理工大学2021-2022学年第二学期2020级面向对象技术与方法(Java语言)期末试题(A卷)

班级________ 学号________ 姓名________ 成绩________

一、填空题(每空1.5分,共15分)

  1. Java中的垃圾回收机制一定程度上消除了程序中的内存泄露memory leak)问题。
  2. 对方法使用修饰符final意味着它不能被重载。
  3. 封装是指把数据成员和相关的方法都放进类中,并使用访问修饰符来控制其可见性。
  4. 标准的IO流包括System.inSystem.outSystem.err
  5. 定义目录过滤器时需要重写FilenameFilter中的accept方法。
  6. Java中的RandomAccessFile类提供了随机访问文件的功能。
  7. .this的含义是当前对象的引用
  8. 可以对象序列化的对象的所属类需要实现Serializable接口。
  9. 使用关键字package为当前java文件中的类指定所属的包。
  10. 子类重写父类的方法的时候,方法的访问权限必须大于或等于父类的方法的访问权限。

二、判断正误(每题1分,共10分)

  1. float x1=1.414f;”语句中等号右边的f是多余的()
  2. 数组有length()方法。( )
  3. Java语言的跨平台性使得它不需要像C语言一样提供sizeof运算符。( )
  4. 内部类inner class)可以访问其外部类enclosing class)中的private成员。( )
  5. 匿名类不一定是内部类( )
  6. Java语言中不同数据类型的长度是固定的,不随机器硬件不同而改变。( )
  7. 对象中必须有属性和方法( )
  8. 类的静态方法可以在该类的对象被创建前调用( )
  9. 同一个类的不同对象共用一个this( )
  10. 当一个方法在运行过程中产生一个异常,如果不及时捕获处理,这个方法会终止,但是整个程序不一定终止。( )。

三、单选题(每题2分,共20分)

  1. 下列( )是合法的标识符 A. 12class B. void C. -5 D. _blank
  2. 下列说法错误的是( ): A. 数组可以动态初始化; B. 数组可以赋值给Object类型的对象; C. 数组创建以后,其长度可以修改; D. 数组可以调用Object类的所有方法;
  3. A有一个方法void method(),要求能够通过类名A直接调用method(),则方法定义应该为( ) A. static void method() B. public void method() C. final void method() D. abstract void method()
  4. 下面关于Java的隐藏和覆盖的说法,正确的是( ) A. 覆盖方法时需要保证方法名完全相同 B. 覆盖方法时不需要参数列表完全相同 C. 覆盖方法时返回值的类型必须完全一样 D. 进行变量隐藏时不能够修改变量类型
  5. Aabc三个public变量成员,B类继承自A,并且增加了自己的public变量成员dC继承自A,增加了自己的public变量成员e,则下列说法中错误的是( ) A. A类拥有c成员 B. B类拥有b成员 C. C类拥有d成员 D. B类拥有c成员
  6. 以下描述正确的是( ) A. 使用FileOutputStream可以将对象进行传输 B. 使用PrintWriter可以将对象进行传输 C. static类型的数据成员不可以被序列化 D. 对象序列化时,所有的数据成员都必须被序列化
  7. 运行下面程序时,会产生什么异常?( )
java
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. 下列循环体执行的次数是( )。

java
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分)

  1. 写出该程序的输出结果 (5分)
java
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分)

java
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);
    }
}
  1. 使用lambda表达式和目录名过滤器列出c:\test文件中的所有txt文件(5分)
  2. 简述Java中垃圾回收机制(5分)
  3. 按注释完成程序(5分)
java
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分)

  1. 定义一个接口ICompute含有一个方法int computer(int n, int m);设计四个类分别实现此接口,完成加减乘除运算;设计一个类UseCompute,类中含有方法:public void useCom(ICompute com, int one, int two),此方法能够用传递过来的对象调用computer方法完成运算,并输出运算的结果。(8分)
  2. 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分)

答案与解析

(一)填空题

  1. 垃圾回收Garbage Collection:Java的垃圾回收机制会自动回收不再被引用的对象所占用的内存,从而减少内存泄露问题。
  2. final:被final修饰的方法不能被重写(重载是指方法名相同,参数列表不同;重写是指子类重新实现父类的方法)。
  3. 访问修饰符(如privateprotectedpublic等):通过这些修饰符来控制类中成员的可见性,实现封装。
  4. System.err:标准的IO流中,System.in是标准输入流,System.out是标准输出流,System.err是标准错误输出流。
  5. accept:在定义目录过滤器时,需要重写FilenameFilter接口中的accept方法来指定过滤规则。
  6. RandomAccessFile:该类提供了对文件的随机访问功能,可以在文件的任意位置进行读写操作。
  7. 当前对象的引用:在类的方法中,this代表调用该方法的当前对象。
  8. Serializable:一个类实现Serializable接口后,其对象才能被序列化,即转换为字节流进行存储或传输。
  9. package:使用package关键字为当前Java文件中的类指定所属的包,便于组织和管理类。
  10. 大于:子类重写父类方法时,方法的访问权限必须大于或等于父类方法的访问权限,以保证多态性的正常运行。

(二)判断正误

  1. 错误:在Java中,1.414double类型常量,若要赋值给float类型变量,需加上后缀f,否则会报错。
  2. 错误:数组有length属性,用于获取数组的长度,而不是length()方法。
  3. 正确:Java语言跨平台,其数据类型的长度是固定的,不依赖于具体的机器硬件,所以不需要sizeof运算符来获取数据类型的大小。
  4. 正确内部类可以访问其外部类的所有成员,包括private成员。
  5. 错误匿名类一定是内部类,它是没有名字的内部类,通常用于创建只使用一次的类对象。
  6. 正确:Java中数据类型的长度是固定的,不随机器硬件不同而改变,保证了代码的可移植性。
  7. 错误:对象不一定必须有属性和方法,例如可以定义一个空类,它的对象就没有属性和方法。
  8. 正确:类的静态方法属于类本身,而不是类的某个对象,所以可以在对象创建前调用。
  9. 错误:每个对象都有自己独立的this引用,指向自身。
  10. 正确:当一个方法抛出异常且未被捕获时,该方法会终止执行,但如果异常没有向上传播到整个程序的顶层,程序不会终止。

(三)单选题

  1. D:标识符不能以数字开头,不能是关键字(如void),也不能包含特殊符号(如-),_blank符合标识符命名规则。
  2. C:数组创建后,其长度是固定的,不能修改。数组可以动态初始化,也可以赋值给Object类型的对象,并且可以调用Object类的所有方法。
  3. A:要通过类名直接调用方法,该方法必须是静态方法,用static修饰。
  4. A:覆盖方法时,方法名、参数列表和返回值类型都必须相同(在Java 5.0及以上版本,返回值类型可以是协变的,即子类方法的返回值类型是父类方法返回值类型的子类);变量隐藏时可以修改变量类型。
  5. CC类继承自A类,没有继承B类的d成员,A类拥有c成员,B类继承自A类,拥有bc成员。
  6. CFileOutputStreamPrintWriter都不能直接传输对象;static类型的数据成员不可以被序列化;对象序列化时,用transient修饰的数据成员不会被序列化。
  7. C:程序中数组z的下标最大为3,访问z[4]会导致ArrayIndexOutOfBoundsException异常;在抛出该异常后,后面的代码不会执行,所以不会出现ArithmeticException异常。
  8. Asuper关键字在子类对象内部指代其父类对象的引用,只能指代直接父类,既可以调用父类的方法,也可以调用父类的属性。
  9. B:第一次循环,x初始值为4,--xx为3,x/y为1,条件成立;第二次循环,--xx为2,x/y为1,条件成立;第三次循环,--xx为1,x/y为0,条件不成立,循环结束,所以循环体执行了2次。
  10. Bbyte类型的取值范围是-128到127,128超出了其取值范围,会报错。

(四)简答题

  1. 输出结果
Bowl(1)
Bowl(2)
Bowl(4)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
Bowl(5)
Table()

解析:在程序运行时,首先会加载静态成员。Table类的静态成员b1b2会被初始化,执行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表达式代码

java
(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文件代码

java
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