设计一个类 Company,该类实现接口 ClassName 中的方法 getClassName(),功能是获取该类的类名称。编写应用程序使用 Company 类。 interface ClassName { public String getClassName() ; } class Company implements ClassName { public String getClassName() { return "Company"; } } public class TestDemo { public static void main(String args[]) { ClassName name = new Company() ; System.out.println(name.getClassName()); } } 程序运行结果: Company 8、 建立一个人类(Person)和学生类(Student)功能要求: A、 Person 中包含 4 个保护型的数据成员 name、address、sex、age 分别为字符串,字符串,字符及整型。表示:姓 名、地址、性别和年龄。一个四参构造方法,一个无参构造方法,及一个输出方法用于显示四种属性。 B、 Student 继承 Person,并增加输出成员 math、english 存放数学和英语成绩。一个六参构造方法,一个两参构造 方法,一个无参构造方法,重写输出方法用于显示全部六种种属性. class Person { private String name ; private String address ; private char sex ; private int age ; public Person() { } public Person(String name, String address, char sex, int age) { super(); this.name = name; this.address = address; this.sex = sex; this.age = age; } public String toString() { return "姓名:" + this.name + ",地址:" + this.address + ",性别:" + this.sex + ",年龄:" + this.age; } // setter、getter略 } class Student extends Person { 第(16)页 共(39)页 private double math ; private double english ; public Student() { } public Student(String name, String address, char sex, int age, double math, double english) { super(name, address, sex, age); this.math = math; this.english = english; } public String toString() { return super.toString() + ",数学成绩:" + this.math + ",英语成绩:" + this.english; } // setter、getter略 } public class TestDemo { public static void main(String args[]) { Student stu = new Student("张三", "北京西城区甲11号德外大街德胜科技园美江大厦 A座 - 6层", ' 男', 25, 90.0, 99.0); System.out.println(stu); } } 程序运行结果: 姓名:张三,地址:北京西城区甲11号德外大街德胜科技 园美江大厦 A座 - 6层,性别:男,年龄:25,数学成绩: 90.0,英语成绩:99.0 9、 定义员工类,具有姓名,年龄,性别属性,并具有构造方法,显示数据方法,定义管理层类,继承员工类,并有自 己的属性:职务,年薪。定义职员类,继承员工类,并有自己的属性:所属部门,月薪。 class Employee { private String name ; private int age ; private char sex ; public Employee() { } public Employee(String name, int age, char sex) { super(); this.name = name; this.age = age; this.sex = sex; } public String toString() { return "雇员姓名:" + this.name + ",年龄:" + this.age + ",性别:" + this.sex; } // setter、getter略 } class Manager extends Employee { 第(17)页 共(39)页 private String job ; private double income ; public Manager() { } public Manager(String name, int age, char sex, String job, double income) { super(name, age, sex); this.job = job; this.income = income; } public String toString() { return super.toString() + ",职位:" + this.job + ",年薪:" + this.income ; } // setter、getter略 } class Staff extends Employee { private String dept ; private double salary ; public Staff() { } public Staff(String name, int age, char sex, String dept, double salary) { super(name, age, sex); this.dept = dept; this.salary = salary; } public String toString() { return super.toString() + ",部门:" + this.dept + ",月薪:" + this.salary ; } // setter、getter略 } public class TestDemo { public static void main(String args[]) { Employee ea = new Manager("张三", 30, '男', "总监", 200000.0); Employee eb = new Staff("李四", 25, '女', "业务部", 1500.0); System.out.println(ea); System.out.println(eb); } } 程序运行结果: 雇员姓名:张三,年龄:30,性别:男,职位:总监,年薪:200000.0 雇员姓名:李四,年龄:25,性别:女,部门:业务部,月薪:1500.0 10、 定义类 Shape 表示一般二维图形。Shape 具有抽象方法 area 和 perimeter,分别计算形状的面积和周长。试定义一些二 维形状类(如矩形、三角形、圆形等),这些类均为 Shape 类的子类。 abstract class Shape { public abstract double area(); public abstract double perimeter(); 第(18)页 共(39)页 } class Rectangle extends Shape { // 矩形 private double wide ; // 宽 private double longs ; // 长 public Rectangle() { } public Rectangle(double wide, double longs) { super(); this.wide = wide; this.longs = longs; } public double area() { return this.longs * this.wide ; } public double perimeter() { return (this.longs + this.wide) * 2; } } class Triangle extends Shape { // 三角形 private double edgea ; // 边长 private double edgeb ; // 边长 private double edgec ; // 边长 public Triangle() { } public Triangle(double edgea, double edgeb, double edgec) { super(); this.edgea = edgea; this.edgeb = edgeb; this.edgec = edgec; } public double area() { return this.edgea * this.edgeb / 2 ; } public double perimeter() { return this.edgea + this.edgeb + this.edgec ; } } class Round extends Shape { // 圆形 private double radius ; // 半径 public Round() { } public Round(double radius) { super(); this.radius = radius; } 第(19)页 共(39)页 public double area() { return this.radius * this.radius * Math.PI; } public double perimeter() { return this.radius * 2 * Math.PI; } } public class TestDemo { public static void main(String args[]) { Shape rectangle = new Rectangle(10.5, 20.6); Shape triangle = new Triangle(10.1, 20.2, 30.3); Shape round = new Round(30.3) ; System.out.println("矩形面积:" + rectangle.area() + ",矩形周长:" + rectangle.perimeter()); System.out.println("三角形面积:" + triangle.area() + ",三角形周长:" + triangle.perimeter()); System.out.println("圆形面积:" + round.area() + ",圆形周长:" + round.perimeter()); } } 程序运行结果: 矩形面积:216.3,矩形周长:62.2 三角形面积:102.00999999999999,三角形周长:60.599999999999994 圆形面积:2884.2647993342534,圆形周长:190.38051480754146 第 4 章、异常的捕获及处理 —— 自我检测(答案) 1、填空题 1、 Throwable下有那两个子类: Error 、 Exception 。 2、 ArthmeticException类表示 算术 异常,ArraysIndexOutOfBoundsException表示 数组越界 3、 一个try代码后面必须跟着若干个 catch 代码段或者一个 finally 代码段。 4、 如果一个方法使用了 throws ,则编译器会强制在使用此方法时进行异常的处理。 5、 异常处理中使用 finally 作为异常的统一出口。 异常。 2、选择题 1、 使用那个关键字可以在程序中手工抛出异常 B 。 A、 throws B、 throw C、 assert D、 class 2、 下面 A 关键字可以用在方法的声明处? A、 throws B、 assert C、 class D、 interface 3、 为了捕获一个异常,代码必须放在下面 A 语句块中。 A、 try 块 B、 catch 块 C、 throws 块 D、 finally 块 4、 下面关于try块的说法正确的是 C 。 A、 try 块后至少应有一个 catch 块 B、 try 块后必须有 finally 块 C、 可能抛出异常的方法应放在 try 块中 D、 对抛出的异常的处理应放在 try 块中 第(20)页 共(39)页 5、 finally块中的代码将 A 。 A、 总是被执行 B、 如果 try 块后面没有 catch 块时,finally 块中的代码才会执行 C、 异常发生时才被执行 D、 异常没有发生时才执行 6、 一个异常将终止 A 。 A、 整个程序 B、 只终止抛出异常的方法 C、 产生异常的 try 块 D、 上面的说法都不对 7、 所有异常的共同父类是 B 。 A、 Error B、 Exception C、 Throwable D、 RuntimeException 3、判断题 1、 一个 try 语句后有多个 catch 时,捕获范围大的异常要放在捕获范围小的异常之后。 ( √ ) 2、 finally 语句可以根据需要有选择的添加。 (√) 4、简答题 1、 简述 RuntimeException 和 Exception 的区别。 答: 异常(Exception)表示程序运行过程中可能出现的非正常状态,运行时异常(RuntimeException)表示虚拟机的通常 操作中可能遇到的异常,是一种常见运行错误。java 编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要 求必须声明抛出未被捕获的运行时异常,即:Exception 定义了必须处理的异常,而 RuntimeException 定义的异常可以选择 性的进行处理。 RuntimeException 是 Exception 的子类; 2、 try、catch、finally 三种语句的功能是什么? 答: try 语句负责捕获程序之中产生的异常; catch 负责匹配异常类型,并且对指定的异常进行处理; finally 作为异常处理的统一出口,不管是否发生异常,都会执行本程序。 3、 简述 Java 中的异常处理机制。 答: (1)、如果程序之中产生了异常,那么会自动的由 JVM 根据异常的类型,实例化一个指定异常类的对象; (2)、如果这个时候程序之中没有任何的异常处理操作,则这个异常类的实例化对象将交给 JVM 进行处理,而 JVM 的默认处理方式就是进行异常信息的输出,而后中断程序执行; (3)、如果程序之中存在了异常处理,则会由 try 语句捕获产生的异常类对象; (4)、与 try 之后的每一个 catch 进行匹配,如果匹配成功,则使用指定的 catch 进行处理,如果没有匹配成功,则向 后面的 catch 继续匹配,如果没有任何的 catch 匹配成功,则这个时候将交给 JVM 执行默认处理; (5)、不管是否有异常都会执行 finally 程序,如果此时没有异常,执行完 finally,则会继续执行程序之中的其他代码, 如果此时有异常没有能够处理(没有一个 catch 可以满足),那么也会执行 finally,但是执行完 finally 之后,将默认交给 JVM 进行异常的信息输出,并且程序中断; 4、 简述 Error 和 Exception 的区别。 答: Error:指的是 JVM 错误,这个时候的程序并没有执行,无法处理; Exception:指的是程序之中出现的错误信息,可以进行异常处理,主要关心 Exception。 5、 列举三个常见的 RuntimeException 子类。 答: NumberFormatException、ClassCastException、NullPointerException 第(21)页 共(39)页 5、编程题 1、 编写应用程序,从命令行输入两个小数参数,求它们的商。要求程序中捕获 NumberFormatException 异常和 ArithmeticException 异常。 class MyMath { public int div(String x, String y) throws NumberFormatException, ArithmeticException { // 出现异常要交给被调用处出 int result = 0; try { int numa = Integer.parseInt(x) ; int numb = Integer.parseInt(y) ; result = numa / numb; // 除法计算 } catch (Exception e) { throw e; // 向上抛 } return result; } } public class TestDemo { public static void main(String args[]) { if (args.length != 2) { System.out.println("程序运行出错!"); System.exit(1) ; // 程序退出 } try { MyMath mm = new MyMath() ; System.out.println(mm.div(args[0], args[1])); // 被调用处处理异常 } catch (Exception e) { e.printStackTrace(); } } } 第 5 章、包及访问控制权限 —— 自我检测(答案) 1、填空题 1、 package 关键字可以定义一个包, import 关键字可以导入包。 2、 Java中存在四种访问权限: private 、 default 、 protected 、 public 。 3、 Java中可以使用 import static 包.类.* 导入一个类的全部静态方法。 4、 jar 命令可以将全部的class打成一个压缩包。 5、 Java中 java.lang 包是自动导入的。 6、 Java程序分为两种形式: Applet 、 Application 。 第(22)页 共(39)页 2、选择题 1、 String和Object类在 A 包中定义的。 A、 java.lang B、 java.util C、 java.net D、 java.sql 2、 C 权限是同一包可以访问,不同包的子类可以访问,不同包的非子类不可以访问。 A、 private B、 default C、 protected D、 public 3、 下列说法正确的一项是 C 。 A、 java.lang.Integer 是接口 B、 String 定义在 java.util 包中 C、 Double 类在 java.lang 包中 D、 Double 类在 java.lang.Object 包中 4、 下列关于包、类和源文件的描述中,不正确的一项是 C 。 A、 一个包可以包含多个类 B、 一个源文件中,只能有一个 public class C、 属于同一个包的类在默认情况不可以互相访问,必须使用 import 导入 D、 系统不会为源文件创建默认的包 5、 定义类时不可能用到的关键字是 C 。 A、 final B、 public C、 protected D、 static 3、判断题 1、 java.lang 包必须由用户手工导入,否则无法使用。 2、 定义包后类的完整名称是:包.类名称。 4、简答题 1、 简述包的作用及使用。 答: 使用包可以将功能近似的类统一管理,同时可以避免项目之中同名类名称冲突问题; 2、 简述 Java 的四种访问权限的区别。 答: Java 一共有四种访问控制权限: · private:只可以在一个类中访问,其他类不允许访问; · default:可以在一个包中访问,但是不同包不允许访问; · protected:可以在同一个包中和不同包的子类所访问,其他包的类不允许访问; · public:可以被所有包的类所访问。 第 6 章、JDK 1.5 新特性 —— 自我检测(答案) (×) (√) 1、填空题 1、 在使用泛型类时,没有指定泛型的类型,则编译会出现 不安全的警告 信息,程序在使用时会使用 Object 类 型进行接收。 2、 通过 ? extends 类 指定泛型的上限,通过 ? super 类 指定泛型的下限。 第(23)页 共(39)页 3、 使用 ? 通配符可以接收全部的泛型类型实例,但却不可修改泛型属性内容。 4、 Java中通过 enum 关键字定义一个枚举,使用此关键字实际上就相当于一个类继承 java.lang.Enum 。 5、 枚举中通过 values() 方法取得枚举的全部内容。 6、 Java提供的三个内建的Annotation是: @Override 、 @Deprecated 、 @SuppressWarnings 。 2、判断题 1、 在枚举类中可以定义抽象方法,而抽象方法只需要实现一次即可。 2、 枚举中可以定义构造方法,但要求每个枚举对象都必须调用此构造方法。 3、 枚举中定义的构造方法可以使用 public 权限声明。 (×) (√) (×) 3、简答题 1、 简述泛型的作用 答: 泛型的主要作用是解决对象向下转型所带来的 ClassCastException,使用泛型之后,类之中的属性或方法中的参数类 型就由调用处来决定,而如果调用处不设置泛型,为了保证程序不出错,则会使用 Object 类型进行定义。 2、 简述枚举的作用及实现特点。 答: 枚举定义出了一个类所能使用的若干几个实例化对象,枚举可以直接采用“枚举类型.对象”的方式取得类中的实例 化对象进行操作。 3、 简述 JAVA SE 中三个内建的 Annotation 的作用。 答: 在 JAVA SE 之中定义了三种 Annotation: · @Override:准确的方法覆写; · @Deprecated:某个结构(类、方法、属性)不再建议被用户所使用; · @SuppressWarnings:压制编译时所产生的警告信息。 4、编程题 1、 定义一个品牌电脑的枚举类,里面只有固定的几个电脑品牌,例如:Lenovo、HP、Dell、Apple、Acer。 enum ComputerBrand { LENOVO("联想"), HP("惠普"), DELL("戴尔"), APPLE("苹果"), ACER("宏基"); private String title; private ComputerBrand(String title) { this.title = title; } @Override public String toString() { return this.title ; } } 第(24)页 共(39)页 第 7 章、多线程 —— 自我检测(答案) 1、填空题 1、 Java多线程可以依靠 继承Thread类 和 实现Runnable接口 两种方式实现。 2、 多个线程操作同一资源的时候需要注意 同步 ,依靠 synchronized 关键字实现,实现手段是: 码块 和 同步方法 ,过多的使用,则会出现 死锁 问题。 3、 Java程序运行时,至少启动 两个 个线程,分别是: main线程 和 gc线程 。 4、 main线程的优先级是 中等优先级 。 5、 线程在生命周期中要经历五种状态,分别是 创建 状态、 就绪 状态、 运行 状态、 堵塞 销毁 状态。 6、 Object类提供的 wait() 、 notify() 、 notifyAll() 三个方法可以控制线程。 同步代 状态、 2、选择题 1、 线程的启动方法是 B 。 A、 run() B、 start() C、 begin() D、 accept() 2、 Thread类提供表示线程优先级的静态常量,代表普通优先级的静态常量是 D 。 A、 MAX_PRIORITY B、 MIN_PRIORITY C、 NORMAL_PRIORITY D、 NORM_PRIORITY 3、 设置线程优先级的方法是 A 。 A、 setPriority() B、 getPriority() C、 getName() D、 setName() 4、 Thread类的 D 方法是不建议使用的? A、 stop() B、 suspend() C、 resume() D、 全部都是 5、 下列 C 关键字通常用赖对对象加锁,从而似的对对象的访问是排他的。 A、 serialize B、 transient C、 synchronized D、 static 3、判断题 1、 Java 中直接调用 Thread 类中的 run()方法可以启动一个线程。 2、 进程是在线程的基础之上的进一步划分。 3、 Java 是多线程的编程语言。 (×) (√) (√) 4、简答题 1、 简述线程两种实现方式及区别? 答: 多线程的两种实现方式都需要一个线程的主类,而这个类可以实现 Runnable 接口或继承 Thread 类,不管使用何种方 式都必须在子类之中覆写 run()方法,此方法为线程的主方法; Thread 类是 Runnable 接口的子类,而且使用 Runnable 接口可以避免单继承局限,以及更加方便的实现数据共享的概 念。 2、 简述死锁的产生。 答: 当多个线程访问某一共享资源时,为保证数据的正确性,需要使用同步进行控制,线程同步指的是某一线程要等待 第(25)页 共(39)页 其他线程对象操作完成之后才可以进行操作,但是在程序之中过多的线程等待就会出现死锁。 5、编程题 1、 设计四个线程对象,两个线程执行减操作,两个线程执行加操作。 class Message { private int data = 10 ; // 初始值 private boolean flag = true; public synchronized void add() { // 加法操作 if (this.flag == false) { // 已经生产过了,不能生产 try { super.wait(); // 等待 } catch (InterruptedException e) { e.printStackTrace(); } } try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("加法操作:" + this.data ++); this.flag = false; // 已经生产完成,修改标志位 super.notify(); // 唤醒等待线程 } public synchronized void subtract() { // 减法操作 if (this.flag == true) { // 未生产,不能取走 try { super.wait(); // 等待 } catch (InterruptedException e) { e.printStackTrace(); } } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("减法操作:" + this.data --); this.flag = true; // 已经取走了,可以继续生产 super.notify(); // 唤醒等待线程 } // setter、getter略 } class Addition implements Runnable { // 定义生产者 第(26)页 共(39)页 private Message msg = null ; public Addition(Message msg) { this.msg = msg ; } @Override public void run() { for (int x = 0; x < 50; x++) { // 加法执行50次 this.msg.add() ; // 加法操作 } } } class Subtraction implements Runnable { // 定义消费者 private Message msg = null ; public Subtraction (Message msg) { this.msg = msg ; } @Override public void run() { for (int x = 0; x < 50; x++) { // 减法执行50次 this.msg.subtract() ; // 执行减法 } } } public class TestDemo { public static void main(String args[]) { Message msg = new Message(); new Thread(new Addition(msg), "加法对象A").start(); // 启动线程 new Thread(new Addition(msg), "家访对象B").start(); // 启动者线程 new Thread(new Subtraction(msg), "减法对象A").start(); // 取得线程 new Thread(new Subtraction(msg), "减法对象B").start(); // 取得线程 } } 第 8 章、常用类库 —— 自我检测(答案) 1、填空题 1、 在java.lang包中提供了两个字符串类,分别是 String 和 StringBuffer。这两个类都是 CharSequence 接 口的子类,字符串类提供的求字符串长度的方法是 public int length() 。 2、 Java中提供的两个大数操作类是: BigInteger 和 BigDecimal 。 3、 对象克隆方法是 Object 类提供的,方法名称是 public Object clone () thorws CloneNotSupportException ,对 象所在的类必须实现 java.lang.Cloneable 接口。 4、 String类的 matches() 、 split() 、 replaceAll() 、 replaceFirst() 四个方法可以使用正则。 5、 通过Object类中的 public Class getClass() 方法可以取得一个类的Class对象。 第(27)页 共(39)页 6、 Constructor类定义在 java.lang.reflect 包中。 7、 Class类对象的三种实例化方式: getClass()方法 、 类.class 、 forName(className) 方法 。 2、选择题 1、 使用Runtime类的 D 方法,可以释放垃圾内存。 A、 exec() B、 run() C、 invoke() 2、 Object类中的 B 方法不能被覆写? A、 toString() B、 getClass() C、 clone() 3、 如果要为对象回收做收尾操作,则应该覆写Object类中的 A、 toString() B、 getClass() C、 clone() D、 gc() D、 finalize() D 方法。 D、 finalize() 3、判断题 1、 任何类的对象数组都可以使用 Arrays.sort()方法进行排序操作。 2、 Random 类存放在 java.lang 包中。 3、 Runtime 类的对象可以直接通过构造方法实例化。 4、 Class 类的对象可以通过关键字 new 进行实例化操作。 5、 可以通过 Class 实例化一个类的对象,但是要求此类必须存在无参构造。 (×) (√) (×) (×) (√) 4、简答题 1、 String 类和 StringBuffer 类的区别是什么?StringBuffer 类提供了那些独特的方法? 答: String 类的内容一旦声明则不可修改,而 StringBuffer 类的内容定义之后可以修改。StringBuffer 类使用 append()方法 可以完成字符串的连接操作,而 String 类使用“+”完成; 特殊方法:insert()、reverse()、replace()。 2、 简述 final、finally、finalize 的区别及作用? 答: final 表示终结器,用于定义不能被继承的父类,不能被覆写的方法,常量; finally 是异常处理的出口; finalize()是 Object 类定义的一个方法,用于执行对象回收前的收尾操作。 3、 解释 Comparable 和 Comparator 的区别。 答: java.lang.Comparable 是在一个类定义的时候默认实现好的接口,里面只有一个 compareTo()方法; java.util.Comparator 是需要单独定义一个比较的规则类,里面有两个方法;compare()、equals()。 5、编程题 1、 定义一个 StringBuffer 类对象,然后通过 append()方法向对象里添加 26 个小写字母,要求每次只添加一次,共添加 26 次。 public class TestDemo { public static void main(String args[]) { StringBuffer buf = new StringBuffer() ; for (char c = 'a' ; c <='z' ; c++){ buf.append(c) ; // 连接字符串 第(28)页 共(39)页 } System.out.println(buf); } } 程序运行结果: abcdefghijklmnopqrstuvwxyz 2、 利用 Random 类产生 5 个 1~30 之间(包括 1 和 30)的随机整数。 import java.util.Random; public class TestDemo { public static void main(String args[]) { Random rand = new Random(); for (int x = 0; x < 5; x++) { System.out.print(rand.nextInt(31) + "、"); } } } 程序运行结果 23、2、20、0、30、 3、 输入一个 email 地址,之后使用正则表达式验证该 email 地址是否正确。 package cn.mldn.demo; public class TestDemo { public static void main(String[] args) throws Exception { String str = "mldnqa@163.net"; String regex = "[a-zA-Z_][a-zA-Z_0-9\\.]*@[a-zA-Z_0-9\\.]+\\.(com|cn|net)"; if (str.matches(regex)) { // 符合于验证要求 System.out.println("TRUE,EMAIL输入合法。"); } else { System.out.println("FLASE,EMAIL输入非法!"); } } } 程序运行结果: TRUE,EMAIL输入合法。 4、 编写正则表达式,判断给定的是否是一个合法的 ip 地址。 public class TestDemo { public static void main(String[] args) throws Exception { String str = "192.168.1.3"; String regex = "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"; if (str.matches(regex)) { // 符合于验证要求 System.out.println("TRUE,IP地址输入合法。"); } else { System.out.println("FLASE,IP地址输入非法!"); } } } 程序运行结果: TRUE,IP地址输入合法。 5、 编写程序,将字符串“1981-09-19 09:07:27.727”变为 Date 型数据。 import java.text.SimpleDateFormat; 第(29)页 共(39)页 import java.util.Date; public class TestDemo { public static void main(String[] args) throws Exception { String str = "1981-09-19 09:07:27.727"; // 字符串 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); Date date = sdf.parse(str); // 将字符串变为日期 System.out.println(date); } } 程序运行结果: Sat Sep 19 09:07:27 CST 1981 第 9 章、Java IO 操作 —— 自我检测(答案) 1、填空题 1、 IO操作的所有类都保存在 java.io 包中。 2、 文件输入流是 FileInputStream、FileReader 、文件输出流 FileOutputStream、FileWriter 。 3、 IO操作中字节流的操作类是 InputStream 、 OutputStream ,字符流的操作类是 Reader 和 Writer 。 4、 System类中提供那个三个常量是对IO有所支持的: out 、 err 、 in 。 5、 序列化对象使用 ObjectOutputStream 、 ObjectInputStream 类,对象所在的类必须实现 Serializable 接口, 才可以自动序列化所有的内容。 6、 transient 关键字可以让类中的属性不被序列化下来。 2、选择题 1、 File类提供了许多管理磁盘的方法。其中,建立目录的方法是 B 。 A、 delete() B、 mkdirs() C、 makedir() D、 exists() 2、 提供println()方法和print()方法的类是 A 。 A、 PrintStream B、 System C、 InputStream D、 DataOutputStream 3、 不同的操作系统使用不同的路径分隔符。静态常量separator表示路径分隔符,它属于的类是 C 。 A、 FileInputStream B、 FileOutputStream C、 File D、 InputStream 4、 下面的说法不正确的是 D 。 A、 InputStream 与 OutputStream 类通常是用来处理字节流,也就是二进制文件 B、 Reader 与 Writer 类则是用来处理字符流,也就是纯文本文件 C、 Java 中 IO 流的处理通常分为输入和输出两个部分 D、 File 类是输入/输出流类的子类 5、 下面的说法正确的是 A 。 A、 InputStream 与 OutputStream 都是抽象类 B、 Reader 与 Writer 不是抽象类 C、 RandomAccessFile 是抽象类 D、 File 类是抽象类 6、 与InputStream相对应的Java系统的标准输入对象是 A 。 A、 System.in B、 System.out C、 System.err D、 System.exit() 第(30)页 共(39)页 7、 FileOutputStream类的父类是 C 。 A、 File B、 FileOutput 8、 InputStreamReader类提供的功能是 D 。 A、 数据校验 B、 文本行计数 C、 OutputStream C、 压缩 D、 InputStream D、 将字节流变为字符流 3、判断题 1、 字节流操作时使用到了缓冲区,字符流操作时没有使用到缓冲区。 2、 File 类用于管理本地磁盘的文件和目录。 3、 通过 read()方法可以从字节输入流读出各种类型的数据。 (×) (√) (√) 4、简答题 1、 简述字节流与字符流操作的区别。 答: 字节流没有使用到缓冲区,而字符流使用了; 处理各种数据都可以通过字节流完成,而在处理中文的时候使用字符流会更好。 2、 简述对象序列化的主要作用。 答: 对象序列化主要是指将内存之中保存的对象以二进制数据流的方式进行传输,要实现序列化的对象所在类必须实现 java.io.Seriliazable 接口。 5、编程题 1、 编写 Java 程序,输入 3 个整数,并求出三个整数的最大值、最小值。 import java.util.Scanner; public class TestDemo { public static void main(String[] args) throws Exception { Scanner scan = new Scanner(System.in); int data[] = new int[3]; // 接收三个输入数据 for (int x = 0; x < data.length;) { System.out.print("请输入第" + (x + 1) + "个数字:"); if (scan.hasNextInt()) { // 输入的是数字 data[x] = scan.nextInt(); // 接收数字 x ++ ; } } int max = data[0] ; // 假设第1个数据为最大值 int min = data[0] ; // 假设第1个数据为最小值 for (int x = 1; x < data.length; x++) { if (min > data[x]) { min = data[x]; } if (max < data[x]) { max = data[x] ; 第(31)页 共(39)页 } } System.out.println("最大值:" + max); System.out.println("最小值:" + min); } } 程序运行结果: 请输入第1个数字:10 请输入第2个数字:20 请输入第3个数字:30 最大值:30 最小值:10 2、 从键盘输入文件的内容和要保存的文件名称,之后根据输入的名称创建文件,并将内容保存到文件之中。 import java.io.File; import java.io.FileOutputStream; import java.io.PrintStream; import java.util.Scanner; public class TestDemo { public static void main(String[] args) throws Exception { Scanner scan = new Scanner(System.in); String fileName = null ; // 保存文件名称 String fileContent = null ; // 保存文件内容 System.out.print("请输入文件名称:"); // 提示信息 scan.useDelimiter("\n") ; // 设置分隔符 if (scan.hasNext()) { // 有输入内容 fileName = scan.next().trim() ; // 接收数据 System.out.print("请输入文件内容:"); if (scan.hasNext()) { fileContent = scan.next().trim() ; // 接收数据 File file = new File(fileName) ; if (!file.getParentFile().exists()) { // 文件目录不存在 file.getParentFile().mkdirs() ; // 创建目录 } PrintStream out = new PrintStream(new FileOutputStream(file)); out.print(fileContent) ; out.close() ; } } } } 程序运行结果: 请输入文件名称:d:\mldnjava\lxh.txt 请输入文件内容:www.mldnjava.cn,北京魔乐科技软件学院! 3、 编写程序,程序运行后,根据屏幕提示输入一个数字字符串,输入后统计有多少个偶数数字和奇数数字。 第(32)页 共(39)页 import java.util.Arrays; import java.util.Scanner; public class TestDemo { public static void main(String[] args) throws Exception { Scanner scan = new Scanner(System.in); scan.useDelimiter("\n") ; String data = null ; // 接收数据 boolean flag = true ; // 循环标记 while(flag) { System.out.print("请输入一串数字:"); if (scan.hasNext()) { data = scan.next().trim() ; // 接收数据 if (data.matches("\\d+")) { // 由数字所组成 flag = false ; // 循环结束 } else { System.out.println("输入数据不是数字,请重新输入!"); } } } int oddCount = 0 ; // 奇数个数 int evenCount = 0 ; // 偶数个数 String result [] = data.split("") ; // 逐个拆分 for (int x = 1 ; x < result.length ; x ++) { int temp = Integer.parseInt(result[x]) ; // 取得每一个数字 if (temp % 2 == 0) { // 是偶数 evenCount ++ ; } else { oddCount ++ ; } } System.out.println("奇数个数:" + oddCount); System.out.println("偶数个数:" + evenCount); } } 程序运行结果: 请输入一串数字:123456789 奇数个数:5 偶数个数:4 第 10 章、Java 网络编程 —— 自我检测(答案) 1、选择题 1、 Socket的工作流程是: C 。 ①、打开连接到 Socket 的输入/输出 第(33)页 共(39)页 ②、按照某个协议对 Socket 进行的读/写操作 ③、创建 Socket ④、关闭 Socket A、 ①③②④ B、 ②①③④ C、③①②④ D、 ①②③④ 2、判断题 1、 java.net 包为网络通讯包。 2、 ServerSocket 类和 Socket 类主要完成 TCP 程序设计。 (√) (√) 第 11 章、Java 类集框架 —— 自我检测(答案) 1、填空题 1、 在类集中存放单值的最大父接口是 Collection ,存放一对值的最大父接口是 Map 。 2、 Set 接口保存的数据是不允许重复的,并且 TreeSet 子类是可以排序的,根据 Comparable接口 排序。 3、 Java类集可以使用的输出方式是: Iterator 、 ListIterator 、 Enumeration 、 foreach 。 4、 在Java中实现栈操作的类是 Stack 。 2、选择题 1、 下面那个类不是Collection的子类 C 。 A、 ArrayList B、 Vector C、 HashMap D、 TreeSet 2、 HashSet子类依靠 C 方法区分重复元素。 A、 toString()、equals() B、 clone()、equals() C、 hashCode()、equals() D、 getClass()、clone() 3、判断题 1、 List 接口中的内容是不能重复的。 2、 TreeSet 是排序类。 3、 Set 接口的内容可以使用 Enumeration 接口进行输出。 4、 Map 接口的内容可以使用 ListIterator 接口进行输出。 (√) (√) (×) (√) 4、简答题 1、 简述 ArrayList 和 Vector 的区别。 答: No. 区别 ArrayList 1 推出时间 JDK 1.2 2 性能 采用异步处理方式,性能更高 3 安全性 非线程安全 第(34)页 共(39)页 Vector JDK 1.0 采用同步处理方式,性能相对较低 线程安全 4 输出 Iterator、ListIterator、foreach Iterator、ListIterator、foreach、Enumeration 2、 简述 HashMap 及 Hashtable 的区别。 答: No. 区别 HashMap Hashtable 1 推出时间 JDK 1.2 JDK 1.0 2 性能 采用异步处理方式,性能更高 采用同步处理方式,性能相对较低 3 安全性 非线程安全 线程安全 4 设置 null 允许将 key 或 value 设置为 null 不允许出现 null,否则出现空指向异常 3、 Set 集合中的内容是不允许重复的,Java 依靠什么来判断重复对象? 答: Java 依靠 Object 类中的 hashCode()和 equals()方法来判断重复对象。 4、 TreeSet 类是允许排序的,Java 依靠什么进行对象的排序操作? 答: 在 TreeSet 类中依靠 Comparable 接口来进行排序。 5、 简述 Collection 和 Collections 的区别。 答: Collection 是一个接口,用于定义集合操作的标准、Collections 是一个工具类,可以操作任意的集合对象。 5、编程题 1、 使用类集实现以下数据表和简单 Java 类的映射实现; 部门编号 部门名称 位置 部门 NUMBER(2) VARCHAR2(10) VARCHAR2(10) FK_ D EPTNO 雇 员编号 部门编号 姓名 职位 领导 基本工资 佣金 雇员 NUMBER(4) NUMBER(2) VARCHAR2(10) VARCHAR2(9) NUMBER(4) NUMBER(7,2) NUMBER(7,2) import java.util.ArrayList; import java.util.Iterator; import java.util.List; class Emp { // emp表映射类 private int empno; private String ename; private String job; private double sal; private double comm; private Emp mgr; // 雇员领导 private Dept dept; // 雇员所属部门 public Emp() { // 无参构造 } public Emp(int empno, String ename, String job, double sal, double comm) { this.empno = empno; this.ename = ename; this.job = job; this.sal = sal; this.comm = comm; 第(35)页 共(39)页 } // 部分setter、getter略 public void setDept(Dept dept) { // 设置雇员所在部门 this.dept = dept; } public Dept getDept() { // 取得雇员所在部门 return this.dept; } public void setMgr(Emp mgr) { // 设置雇员领导 this.mgr = mgr; } public Emp getMgr() { // 取得雇员领导 return this.mgr; } @Override public int hashCode() { final int prime = 31; int result = 1; long temp; temp = Double.doubleToLongBits(comm); result = prime * result + (int) (temp ^ (temp >>> 32)); result = prime * result + ((dept == null) ? 0 : dept.hashCode()); result = prime * result + empno; result = prime * result + ((ename == null) ? 0 : ename.hashCode()); result = prime * result + ((job == null) ? 0 : job.hashCode()); result = prime * result + ((mgr == null) ? 0 : mgr.hashCode()); temp = Double.doubleToLongBits(sal); result = prime * result + (int) (temp ^ (temp >>> 32)); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Emp other = (Emp) obj; if (Double.doubleToLongBits(comm) != Double .doubleToLongBits(other.comm)) return false; if (dept == null) { if (other.dept != null) return false; 第(36)页 共(39)页 } else if (!dept.equals(other.dept)) return false; if (empno != other.empno) return false; if (ename == null) { if (other.ename != null) return false; } else if (!ename.equals(other.ename)) return false; if (job == null) { if (other.job != null) return false; } else if (!job.equals(other.job)) return false; if (mgr == null) { if (other.mgr != null) return false; } else if (!mgr.equals(other.mgr)) return false; if (Double.doubleToLongBits(sal) != Double.doubleToLongBits(other.sal)) return false; return true; } @Override public String toString() { // 取得雇员信息 return "雇员编号:" + this.empno + ",姓名:" + this.ename + ",职位:" + this.job + ",工资:" + this.sal + ",佣金:" + this.comm; } } class Dept { // dept表映射类 private int deptno; private String dname; private String loc; private List emps; // 多个雇员 public Dept() { // 无参构造 this.emps = new ArrayList() ; } public Dept(int deptno, String dname, String loc) { this() ; // 调用无参构造 this.deptno = deptno; this.dname = dname; this.loc = loc; } // 部分setter、getter略 public void setEmps(List emps) { 第(37)页 共(39)页 this.emps = emps; } public List getEmps() { return emps; } @Override public String toString() { // 取得部门信息 return "部门编号:" + this.deptno + ",部门名称:" + this.dname + ",位置:" + this.loc; } } public class TestDemo { public static void main(String args[]) { // 1、第一层配置关系 Dept dept = new Dept(10, "ACCOUNTING", "New Yrok"); Emp empa = new Emp(7369, "SMITH", "CLERK", 800.0, 0.0); Emp empb = new Emp(7566, "ALLEN", "MANAGER", 2450.0, 0.0); Emp empc = new Emp(7839, "KING", "PRESIDENT", 5000.0, 0.0); empa.setMgr(empb); // 设置雇员和领导的关系 empb.setMgr(empc); // 设置雇员和领导的关系 empa.setDept(dept); // 每个雇员属于一个部门 empb.setDept(dept); // 每个雇员属于一个部门 empc.setDept(dept); // 每个雇员属于一个部门 // 每一个部门有多个雇员,通过对象数组表示多个雇员 dept.getEmps().add(empa) ; dept.getEmps().add(empb) ; dept.getEmps().add(empc) ; // 2、第二层取得关系 System.out.println(dept); Iterator iter = dept.getEmps().iterator() ; while (iter.hasNext()) { Emp emp = iter.next() ; System.out.println(emp); if (emp.getMgr() != null) { // 有领导 System.out.println("\t" + emp.getMgr()); } System.out.println("---------------------------------------------------"); } } } 程序运行结果: 部门编号:10,部门名称:ACCOUNTING,位置:New Yrok 雇员编号:7369,姓名:SMITH,职位:CLERK,工资:800.0,佣金:0.0 雇员编号:7566,姓名:ALLEN,职位:MANAGER,工资:2450.0,佣金:0.0 --------------------------------------------------- 雇员编号:7566,姓名:ALLEN,职位:MANAGER,工资:2450.0,佣金:0.0 第(38)页 共(39)页 雇员编号:7839,姓名:KING,职位:PRESIDENT,工资:5000.0,佣金:0.0 --------------------------------------------------雇员编号:7839,姓名:KING,职位:PRESIDENT,工资:5000.0,佣金:0.0 --------------------------------------------------- 第 12 章、Java 数据库操作 —— 自我检测(答案) 1、填空题 1、 要想执行数据库更新的操作接口是: Statement 和 PreparedStatement 。 3、 数据库查询结果使用 ResultSet 接口保存。 4、 JDBC中通过 Class 类加载数据库驱动程序。 2、选择题 1、 下列 C 不是getConnection()方法的参数? A、 数据库用户名 B、 数据库的访问密码 C、 JDBC 驱动器的版本 D、 连接数据库的 URL 2、 Statement接口中的executeQuery(String sql)方法返回的数据类型是 D 。 A、 Statement 接口实例 B、 Connection 接口实例 C、 DatabaseMetaData 类的对象 D、 ResultSet 类的对象 3、 下列不属于更新数据库操作的步骤的一项是 C A、 加载 JDBC 驱动程序 B、 定义连接的 URL C、 执行查询操作 D、 执行更新操作 3、判断题 1、 JDBC 的驱动程序要在 classpath 中进行配置。 (√) 2、 PreparedStatement 是 Statement 的子接口,使用 PreparedStatement 要比使用 Statement 性能更高。 ( √ ) 第(39)页 共(39)页