Java期末复习 题型:
程序设计题,每题8分,共5题利用Java完成一些基本算法的设计与实现,涉及Java基本语法、面向对象技术、异常、输入输出、多线程
程序阅读题,每题10分,共3题阅读程序回答问题,包括输出结果、修改程序等,涉及Java基本语法、面向对象技术、异常等。
综合应用题,每题15分,共2题利用Java面向对象技术对具体业务场景进行设计。
主要考察知识点Java基本语法 (利用Java完成一些基本算法的设计与实现),面向对象(类定义、新建、成员变量、成员方法、main方法、重写和重载、抽象类和接口、继承与多态)、异常(try catch、throws/throw、自定义异常)、输入输出(文件的读写操作)、多线程(Thread、Runnable 接口,run方法)
程序设计题 第二份作业前13题与递归部分,最后两节课的课上代码
题1:将源文件的内容复制到目标文件中,实现文件复制的功能。
1 2 3 4 5 6 7 8 9 10 11 public static void fileCopy (String src, String dsc) throws Exception { DataInputStream dis = new DataInputStream (new FileInputStream (src)); DataOutputStream dos = new DataOutputStream (new FileOutputStream (dsc)); byte [] buf = new byte [4 * 1024 * 1024 ]; int n; while ((n = dis.read(buf)) != -1 ) { dos.write(buf, 0 , n); } dis.close(); dos.close(); }
题2:生成十个随机数,在屏幕上输出,求和,求平均值,求最大值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 import java.io.FileOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.Random; public class RandomData { public static void main (String[] args) throws IOException { DataOutputStream dos = new DataOutputStream (new FileOutputStream ("d:/data.dat" )); Random r = new Random (); int sum = 0 ; int max = Integer.MIN_VALUE; for (int i = 1 ; i <= 10 ; i++) { int v = r.nextInt(100 ) + 1 ; dos.writeInt(v); System.out.println("Number " + i + ": " + v); sum += v; if (v > max) { max = v; } } double average = (double ) sum / 10 ; System.out.println("Sum: " + sum); System.out.println("Average: " + average); System.out.println("Max: " + max); dos.close(); } }
题3:创建两个线程,每个线程打印:-1,-2,-3….. -10
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class Ain extends Thread { @Override public void run () { for (int i = 0 ; i < 10 ; i++) { System.out.println("-" + i + "--" + getName()); } } } public class TestThread { public static void main (String[] args) { new Ain ().start(); new Ain ().start(); } }
题4:数位分解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class NumberExtractor { public static void main (String[] args) { int number = 1234 ; int ones = number % 10 ; System.out.println("个位数字: " + ones); int tens = (number / 10 ) % 10 ; System.out.println("十位数字: " + tens); int hundreds = (number / 100 ) % 10 ; System.out.println("百位数字: " + hundreds); } }
题5:奇偶数判断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import java.util.Scanner; public class OddOrEvenChecker { public static void main (String[] args) { Scanner scn = new Scanner (System.in); int i = scn.nextInt(); if (number % 2 == 0 ) { System.out.println(number + " 是偶数。" ); } else { System.out.println(number + " 是奇数。" ); } scanner.close(); } }
题6:使用递归实现如下的方法:
s(n)=s(n-1)+n 当n>0时
s(0)=0 当n=0时
程序设计要求:
1)设计实现递归方法,完成s(n)的功能。
2)在public static void main(String[] args)方法中,通过Scanner类读入一个整数值,如:100,然后通过调用1)定义的递归方法,向这个方法传入刚读入的那个值进去,按指定格式在屏幕上输出结果。
输入:请输入一个正整数: 100
输出:和=5050
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import java.util.Scanner;public class test_6 { public static void main (String[] args) { System.out.println("请输入一个正整数:" ); Scanner scanner = new Scanner (System.in); int n = scanner.nextInt(); int sum = s(n); System.out.println(sum); scanner.close(); } public static int s (n) { if (n==0 ) return 0 ; else { return s(n-1 )+n; } } }
题7:使用递归实现如下的方法:gcd(a,b)表示整数a和b的最大公约数
gcd(a,b)=gcd(b,a%b) 当b<>0时
gcd(a,b)=a 当b=0时
程序设计要求:
1)设计实现递归方法,完成gcd(a,b)的功能。
2)在public static void main(String[] args)方法中,通过Scanner类读入两个整数值,如:12 8,然后通过调用1)定义的递归方法,向这个方法传入刚读入的两个值进去,按指定格式在屏幕上输出结果。
输入:
请输入两个正整数: 12 8
输出:
最大公约数是:4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import java.util.Scanner;public class test_7 { public static void main (String[] args) { System.out.println("请输入两个正整数:" ); Scanner scanner = new Scanner (System.in); int a = scanner.nextInt(); int b = scanner.nextInt(); int res = gcd(a,b); System.out.println(res); scanner.close(); } public static int gcd (int a,int b) { if (b==0 ){ return a; } else { return gcd(b,a%b); } } }
题8:
使用递归实现如下的方法:著名的“Ackman”方法。m和n都是整数
Ack(0,n)=n+1 当n>=0时
Ack(m,0)=Ack(m-1,1) 当m>=1时
Acm(m,n)=Ack(m-1,Ack(m,n-1)) 当m和n都>=1时
程序设计要求:
1)设计实现递归方法,完成Acm(m,n)的功能。
2)在public static void main(String[] args)方法中,通过Scanner类读入一个整数值,如:12 ,然后通过调用1)定义的递归方法,向这个方法传入刚读入的两个值进去,按指定格式在屏幕上输出结果。
输入:
请输入两个正整数: 1 1
输出:
Acm(1,1)=……
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public class test_8 { public static void main (String[] args) { Scanner scanner = new Scanner (System.in); System.out.print("请输入两个正整数:" ); int m = scanner.nextInt(); int n = scanner.nextInt(); int result = calculateAckermann(m, n); System.out.println("Acm(" + m + ", " + n + ")=" + result); scanner.close(); } public static int calculateAckermann (int m, int n) { if (m==0 ){ return n+1 ; }else if (n==0 ){ return calculateAckermann(m-1 ,n); }else { return calculateAckermann(m - 1 , calculateAckermann(m, n - 1 )); } } }
题9:使用递归实现如下的功能:从键盘上读入一个非负整数,屏幕上输出这上整数的倒序的十进制数。
如:键盘上输入2456,则屏幕输出6542
程序设计要求:
1)设计一个递归方法,完成:对给定的参数n(如:调用时传给n的值是2465),在该方法内部,通过递归的方式,计算并返回该参数的倒序所对应的整数值(注意:不是在屏幕上打印,而是计算出倒序的值并返回出来 )。
算法提示 :对于2456,其进行递归方式的计算过程如下:
(2456 ,0) (245,6) (24,65) (2,654) (0,6542) 6542
2)在public static void main(String[] args)方法中,通过Scanner类读入一个整数值,如:2456 ,然后通过调用1)定义的递归方法,向这个方法传入刚读入的值进去,将该方法的返回值,在屏幕上按指定的格式输出。
输入:
请输入一个正整数: 12456
输出:
12456的倒序是:65421
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import java.util.Scanner; public class ReverseNumber { public static int reverseNumber (int n) { if (n == 0 ) { return 0 ; } else { int lastDigit = n % 10 ; int reversedRemaining = reverseNumber(n / 10 ); return lastDigit * (int ) Math.pow(10 , (int ) (Math.log10(n) + 1 )) + reversedRemaining; } } public static void main (String[] args) { Scanner scanner = new Scanner (System.in); System.out.print("请输入一个正整数:" ); int n = scanner.nextInt(); int reversed = reverseNumber(n); System.out.println(n + "的倒序是:" + reversed); scanner.close(); } }
使用stringbuffer实现
1 2 3 4 5 6 7 8 9 public class ReverseNumberWithStringBuffer { public static void main (String[] args) { Scanner scanner = new Scanner (System.in); int n = scanner.nextInt(); StringBuffer sb = new StringBuffer (String.valueOf(n)); sb.reverse(); System.out.println(sb.toString()); } }
面向对象快速学习 类与对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class Car { String color; int speed; int seat; public void run () { System.out.println("车能跑" ); } public static void main (String[] args) { Car c = new Car (); c.run(); c.color = "绿色" ; c.speed = 120 ; c.seat = 5 ; System.out.println(c.color); } }
this关键字 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public class Car { String color; int speed; int seat = 5 ; public void run () { System.out.println("车能跑" ); } public void fly () { System.out.println(this .color+"颜色的车会飞" ); } public static void main (String[] args) { Car c = new Car (); c.run(); c.color = "红色" ; c.speed = 120 ; c.fly(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class Car { String color; int speed; int seat = 5 ; public void fly (String color) { System.out.println(this .color+"颜色的车会飞,飞在" +color+"颜色的云彩里" ); } public static void main (String[] args) { Car c = new Car (); c.color = "红色" ; c.speed = 120 ; c.fly("黑色" ); } }
输出:绿色颜色的车会飞,飞在黑色颜色的云彩里。
构造方法 在创建对象的时候,自动调用的方法。
作用:在创建对象时设置属性信息。
语法:
public 类名(传参){
}
注意:
没有返回值这一项。
在我们new的时候,自动调用构造方法。
源程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class Car { String color; int speed; int seat = 5 ; public void run () { System.out.println(this .color+"的车在跑" ); } public static void main (String[] args) { Car c = new Car (); c.color = "红色" ; c.speed = 120 ; Car c2 = new Car (); c2.color = "绿色" ; c2.speed = 180 ; c.run(); c2.run(); } }
改程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class Car { String color; int speed; int seat = 5 ; public Car (String color,int speed) { this .color = color; this .speed = speed; } public void run () { System.out.println(this .color+"的车在跑" ); } public static void main (String[] args) { Car c = new Car ("红色" ,120 ); Car c2 = new Car ("绿色" ,180 ); c.run(); c2.run(); } }
构造方法重载 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class Daxia { String name; String waihao; int age; String bangPai; public Daxia (String name,int age,String bangPai) { this .name = name; this .age = age; this .bangPai = bangPai; } public Daxia (String name,int age,String bangPai,String waohao) { tbis(name,age,bangPai); this .waihao = waihao; } public static void main (String[] args) { Daxia dx1 = new Daxia ("岳不群" ,18 ,"华山派" ); Daxia dx2 = new Daxia ("武松" ,19 ,"梁山" ,"行者" ); } }
static(静态) 特定:
数据共享
属于类的,并不属于对象
优先于对象产生的
创建对象的过程(静态构造器->通用构造器->构造方法->创建对象)
由于对象创建在静态构造之后,所以在静态构造中不能用this。
静态的内容使用类名去访问
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class Person { String name; static String country = "大清" ; String address; public Person (String name,String country,String address) { this .name = name; this .country = country; this .address = address; } public static void main (String[] args) { Person p1 = new Person ("赵铁柱" ,"八大胡同" ); Person p2 = new Person ("李小花" ,"朝阳门" ); Person.country = "民国" ; System.out.println(p1.country); System.out.println(p2.country); } }
输出:
民国
民国
访问权限
关键字
权限
public
公共的,所有人都可以访问
default
包含访问权限,在自己包内可以随意访问
private
私有的
getter&setter 成员变量一般使用private来声明,保护成员变量不被胡乱地赋值。
setter:主要是给成员变量赋值,做一定的保护。
getter:从成员变量中获取数据。
Person.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package com.wxq.entity;public class Person { private String name; private int age; public void setName (String name) { this .name = name; } public void setAge (int age) { this .age = age; } public String getName () { return this .name; } public int getAge () { return this .age; } public void eat () { System.out.println(this .name+"在吃东西" ); } }
TestPerson.java
1 2 3 4 5 6 7 8 9 10 11 12 package com.wxq.entity;public class TestPerson { public static void main (String[] args) { Person p = new Person (); p.setName("吴秀全" ); p.setAge("20" ); p.eat(); System.out.println(p.getName()); System.out.println(p.getAge()); } }
继承 子类可以自动拥有父类中除了私有内容外的其他所有内容。
public class 类 extends 父类{
}
作用:简化代码的开发。
子类对父类进行拓展。
User.java
1 2 3 4 5 6 7 package com.wxq.login;public class User { public void login () { System.out.println("我要登录" ); } }
Admin.java
1 2 3 4 5 package com.wxq.login;public class Admin extends User { }
Test.java
1 2 3 4 5 6 7 8 package com.wxq.login;public class Test { public static void main (String[] args) { Admin a = new Admin (); a.login(); } }
super关键字 super表示父类中的内容
this表示自己类中的内容
用super和this来区分父类和子类中重名的内容
创建对象的过程:先创建父类的对象,然后创建子类的对象
super作用:
super可以获取到父类中的内容
可以调用父类中的构造方法,必须写在子类构造方法的第一行,如果父类的构造是无参数的,可以不写。如果父类没有无参数的构造,必须要写super。
Hero.java
1 2 3 4 5 6 7 public class Hero { String name = "英雄" ; public Hero (String name) { System.out.println("我是父类的构造方法" ); this .name = name; } }
SunWuKong.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class SunWuKong extends Hero { String name = "孙大圣" ; public SunWuKong () { super ("猪八戒" ); System.out.println("我是子类的构造方法" ); } public void eat () { System.out.println(super .name); System.out.println(this .name+"在吃桃子" ); } public static void main (String[] args) { SunWuKong s = new SunWuKong (); s.eat(); } }
输出:
我是父类的构造方法
我是子类的构造方法
猪八戒
孙大圣在吃桃子
方法的重写 重写:子类对父类中提供的方法进行重新定义
语法:子类和父类中的方法声明完全一致
方法的重写=方法的覆盖
LiYuan.java
1 2 3 4 5 public class LiYuan { public void makecountry () { System.out.println("李渊想建立一个自己的国家" ); } }
LiShiMin.java
1 2 3 4 5 6 7 8 9 10 11 12 public class LiShiMin extends LiYuan { public void makecountry () { super .makecountry(); System.out.println("李世民想建立一个自己的国家" ); } public static void main (String[] args) { LiShiMin lsm = new LiShiMin (); lsm.makecountry(); } }
输出:
李渊想建立一个自己的国家
李世民想建立一个自己的国家
多态 多态:同一个对象拥有多种形态
作用:把不同的数据类型进行统一,让程序有超强的可扩展性
缺点:屏蔽掉子类中的特有的方法,要向下转型
Animal.java
1 2 3 4 5 public class Animal { public void eat () { System.out.println("动物在吃" ); } }
Cat.java
1 2 3 4 5 public class Cat extends Animal { public void eat () { System.out.println("猫吃鱼" ); } }
Dog.java
1 2 3 4 5 public class Dog extends Animal { public void eat () { System.out.println("狗吃骨头" ); } }
Person.java
1 2 3 4 5 6 public class Person { public void feed (Animal ani) { ani.eat(); } }
Client.java
1 2 3 4 5 6 7 8 9 10 11 public class Client { public static void main (String[] args) { Animal c = new Cat (); Animal d = new Dog (); Person p = new Person (); p.feed(c); p.feed(d); } }
final关键字
被final修饰的变量不可改变,又被称为常量。
被final修饰的方法不可以被重写。
被final修饰的类不可以被继承。
抽象 在java中:只声明,不实现。
1 2 3 4 5 6 7 public abstract class Animal { public abstract void eat () ; public void smell () { System.out.println("smell" ); } }
1 2 3 4 5 public class Cat extends Animal { public void eat () { System.out.println("猫吃鱼" ); } }
1 2 3 4 5 6 7 public class Client { public static void main (String[] args) { Cat c = new Cat (); c.eat(); } }
抽象方法:使用abstract来修饰,不可以有方法体,直接使用分号结束即可
抽象类:如果一个类中有抽象方法,这个类必须是一个抽象类。
特点:
抽象类不可以创建对象
抽象类的子类,必须重写父类的方法,否则,子类必须也是抽象类,强制要求子类中必须有哪些方法。
接口
接口实际上是一种特殊的抽象类
接口中所有的方法都是抽象方法
接口使用interface来声明
类只能单继承,但是接口支持多实现
接口具有多态性,接口可以把很多不相关的内容进行整合。
接口中所有的方法都是抽象方法,都是公开的,接口中所有的变量都是全局静态变量(public static final)。 7.
Valuable.java
1 2 3 4 5 6 7 8 9 10 11 12 public interface Valuable { public abstract void getMoney () ; }
Protectable.java
1 2 3 public interface Protectable { public abstract void cang () ; }
Animal.java
1 2 3 4 5 public abstract class Animal { public void eat () { System.out.println("在吃" ); }; }
Gold.java
1 2 3 4 5 public class Gold implements Valuable { public void getMoney () { System.out.println("黄金" ); }; }
Panda.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class Panda extends Animal implements Protectable ,Valuable{ @Override public void eat () { System.out.println("熊猫吃竹子" ); } @Override public void cang () { System.out.println("藏在山里" ); } @Override public void getMoney () { System.out.println("可以换黄金" ); } }
Test.java
1 2 3 4 5 6 7 8 9 10 11 12 13 public class Test { public static void main (String[]args) { Panda p = new Panda (); Animal ani = new Panda (); Valuable v = new Panda (); Protectable pro new Panda (); p.eat(); } }
成员变量的初始化 java中所有的变量必须先声明,再赋值才能使用。
java中的成员变量,在创建对象的时候,都会执行一次初始化操作,都会给一个默认值。
基本数据类型默认值都是0
引用数据类型Null
object 在java中所有的类都要继承object
object是一个类,所有类的根。
异常处理 当程序执行的时候出现了异常,那么Java虚拟机会帮助我们处理,
但Java虚拟机处理的方式比较武断,直接终止程序的执行。
1.自己处理异常 通过try catch 语句块来处理
1.1单个异常处理 1 2 3 4 5 6 7 try { }catch (异常类型 异常名称){ }finally { }
举例:
1 2 3 4 5 6 7 8 9 10 11 12 public class ExceptionDemo { public static void main (String[]args) { System.out.println("第一段代码" ); int i=10 ; try { System.out.println(i/0 ); }catch (ArithmeticException e) { System.out.println("除数为0" ); } System.out.println("第二段代码" ); } }
注:其中的ArithmeticException可以用其父类Exception或者RuntimeException代替
1.2多个异常处理 1 2 3 4 5 6 7 8 try { }catch (Exception_1 | Exception_2 |…| Exception_n e) { }finally { }
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class ExceptionDemo { public static void main (String[]args) { System.out.println("第一段代码" ); int i=10 ; String str = null ; int [] arr = new int [3 ]; try { System.out.println(i/0 ); System.out.println(str.length()); arr[10 ]=100 ; }catch (ArithmeticException e1) { System.out.println("除数为0" ); }catch (NullPointException e2){ System.out.println("空指针" ); }catch (ArrayIndexOutOfBoundsException e3){ System.out.println("数组下标越界" ); }catch (Exception e){ e.printStackTrace(); } System.out.println("第二段代码" ); } }
注:
try块中有多行代码,都有可能出现异常信息,程序执行的时候是从上往下执行的,当碰到异常情况就会跳出,剩余的代码就不执行了。
catch中子类在前面,父类在后面。
2.将异常抛出 通过throws关键字将异常交给调用者来处理。
throws作用:在定义一个方法的时候可以使用throws关键字声明,使用throws关键字声明的方法表示此方法不处理异常,而交给方法的调用者进行处理。
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import java.text.SimpleDateFormat;public class ExceptionDemo { public static void main (String[]args) { String str = "2024-06-22" ; SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd" ); try { sdf.parse(str); }catch (ParseException e){ e.printStackTrace(); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import java.text.ParseException;public class ExceptionDemo { public static void main (String[]args) { try { clac(); } catch (Exception e){ e.printStackTrace(); } } public static int calc () throws ArithmeticException,NullPointerException,Exception{ int a=10 ; int b=0 ; int result = a/b; return result; } }
throws的使用格式
1 2 3 [修饰符] 返回值类型 方法名(参数列表)[throws 异常类1 ,异常类2 ,···]{ }
注意:重写一个方法时,它所声明的异常范围不能被扩大。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class ExceptionDemo { public static void main (String[]args) { } interface IPerson { void sleep () throws Exception{ System.out.println("sleep" ); } } class User implements IPerson { @Override public void sleep () throws NullpointerException{ System.out.println("I'm sleeping" ); } } }
throw关键字 举例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import java.text.ParseException;public class ExceptionDemo { public static void main (String[]args) { try { clac(); } catch (Exception e){ e.printStackTrace(); } } public static int calc () throws ArithmeticException{ int a=10 ; int b=0 ; if (b==0 ){ throw new ArithmeticException ("除数为0,不能运算." ); } int result = a/b; return result; } }
throw 和 throws 和throwable 的区别
throws用在方法名后面,跟的是异常类名,throw是用在方法体中,跟的异常对象
throws可以跟多个异常类名,用逗号隔开,throw只能抛出一个异常对象
throws表示抛出异常,由该方法的调用者来处理,throw表示抛出异常,由方法体内的语句处理。
throws表示出现异常的一种可能性,并不一定发生这些异常,throw则是抛出了具体的异常,真实地产生了一个Exception。