🍵 Java是当今世界最重要、使用最广泛的计算机语言之一,全球每天有超百万的开发者在用Java进行开发。
1 异常处理
- 异常处理
- 异常又称例外,是一个在程序执行期间发生的事件,中断正在执行程序的正常指令流。
- 异常产生的三种原因
- Java内部错误发生异常,Java虚拟机产生的异常。
- 编写的程序代码错误所产生的异常,例如:空指针异常、数组越界异常等。
- 通过
throw
语句手动生成的异常,用于告知该方法的调用者一些必要信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import java.util.Scanner;
public class Test137 { public static void main(String[] args) { System.out.print("请输入您的选择(1~3之间的整数):"); Scanner input = new Scanner(System.in); int num = input.nextInt(); switch (num) { case 1: System.out.println("One"); break; case 2: System.out.println("Two"); break; case 3: System.out.println("Three"); break; default: System.out.println("Error"); break; } } }
|
1-1 异常类型
- 异常类型
- 在Java中,所有的异常类型都是内置类java.lang.Throwable类的子类。
- Throwable分为Error(错误)和Exception(异常)两个子类,异常又分为运行时、非运行时异常。
- Error定义了在通常环境下不希望被程序捕获的异常,一般指JVM错误,如堆栈溢出。
- Exception用于应用程序可能出现的异常情况,也是用来创建自定义异常类型类的类。
- 运行时异常是RuntimeException类及其子类异常,不检查异常,程序中可选择捕获处理。
- 非运行时异常是RuntimeException类以外的异常,属于Exception类及其子类,必须处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class StackOverflow { public static void test(int i) { if (i == 0) { return; } else { test(i++); } } }
public class Test138 { public static void main(String[] args) { StackOverflow.test(3); } }
|
1-2 基本结构
- 基本结构
- 异常处理通过5个关键字实现:try、catch、throw、throws、finally。
- try..catch用于捕获并处理异常,throws用于声明可能会出现的异常。
- throw用于抛出异常,finally则用于在任何情况下都必须执行的代码。
(1) try…catch语句
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
| import java.util.Scanner;
public class Test139 {
public static void main(String[] args) { Scanner scanner = new Scanner(System.in); String name = ""; int age = 0; String sex = ""; try { System.out.print("请输入学生姓名:"); name = scanner.next(); System.out.print("请输入学生年龄:"); age = scanner.nextInt(); System.out.print("请输入学生性别:"); sex = scanner.next(); } catch (Exception e) { e.printStackTrace(); System.out.println("输入的年龄有误!"); } System.out.println("姓名:" + name); System.out.println("年龄:" + age); } }
|
(2) 多重catch语句
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| import java.util.Date; import java.io.IOException; import java.text.DateFormat; import java.io.BufferedReader; import java.io.FileInputStream; import java.text.ParseException; import java.io.InputStreamReader; import java.text.SimpleDateFormat; import java.io.FileNotFoundException;
public class Test140 {
public static void main(String[] args) { Date date = readDate(); System.out.println("读取的日期 = " + date); }
public static Date readDate() { FileInputStream readfile = null; InputStreamReader ir = null; BufferedReader in = null; try { readfile = new FileInputStream("./files/readme.txt"); ir = new InputStreamReader(readfile); in = new BufferedReader(ir); String str = in.readLine(); if (str == null) { return null; } DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); Date date = df.parse(str); return date; } catch (FileNotFoundException e) { System.out.println("处理FileNotFoundException..."); e.printStackTrace(); } catch (IOException e) { System.out.println("处理IOException..."); e.printStackTrace(); } catch (ParseException e) { System.out.println("处理ParseException..."); e.printStackTrace(); } return null; } }
|
(3) try catch finally
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 31 32 33 34 35 36 37 38
| import java.util.Scanner;
public class Test141 {
public static void main(String[] args) { Scanner input = new Scanner(System.in); String[] pros = { "记事本", "计算器", "浏览器" }; try { for (int i = 0; i < pros.length; i++) { System.out.println(i + 1 + "、" + pros[i]); } System.out.print("是否运行程序:"); String answer = input.next(); if (answer.equals("y")) { System.out.print("输入程序编号:"); int no = input.nextInt(); System.out.println("正打开" + pros[no - 1] + "..."); } } catch (Exception e) { e.printStackTrace(); } finally { System.out.println("欢迎下次使用..."); } } }
|
1-3 资源管理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import java.io.FileReader; import java.io.IOException; import java.io.PrintStream; import java.io.BufferedReader; import java.io.FileOutputStream;
public class Test142 {
public static void main(String[] args) throws IOException { try ( BufferedReader br = new BufferedReader(new FileReader("Test142.java")); PrintStream ps = new PrintStream(new FileOutputStream("./files/input.txt"))) { System.out.println(br.readLine()); ps.println("Java7中的自动资源管理!"); } } }
|
1-4 声明和抛出
- 声明和抛出
- Java中除了捕获异常和处理异常,还包括了声明异常(throws)和抛出异常(throw)。
- throws声明异常但不一定发生这些异常,执行throw则一定抛出一个具体异常类型。
- 可通过throws在方法上声明该方法要抛出的异常,在方法内部通过throw抛出异常。
- throws可由系统自动将所有捕获的异常抛给上级方法,throw则需要开发自己捕获。
(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 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import java.io.IOException; import java.io.FileInputStream;
public class Test143 {
public void readFile() throws IOException { FileInputStream file = new FileInputStream("./files/input.txt"); int f; while ((f = file.read()) != -1) { System.out.print((char) f); f = file.read(); } file.close(); }
public static void main(String[] args) { Test143 t = new Test143(); try { t.readFile(); } catch (IOException e) { System.out.println(e); } } }
class Sub extends Test143 { }
|
(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 31 32 33 34 35 36 37
| import java.util.Scanner;
public class Test144 { public boolean validateUserName(String username) { boolean con = false; if (username.length() > 8) { for (int i = 0; i < username.length(); i++) { char ch = username.charAt(i); if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) { con = true; } else { con = false; throw new IllegalArgumentException("用户名只由字母和数字组成!"); } } } else { throw new IllegalArgumentException("用户名的长度必须大于八位!"); } return con; }
public static void main(String[] args) { Test144 t = new Test144(); Scanner input = new Scanner(System.in); System.out.print("输入用户名:"); String username = input.next(); try { boolean con = t.validateUserName(username); if (con) { System.out.println("用户名正确!"); } } catch (IllegalArgumentException e) { System.out.println(e); } } }
|
1-5 多异常捕获
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class Test145 {
public static void main(String[] args) { try { int a = Integer.parseInt(args[0]); int b = Integer.parseInt(args[1]); int c = a / b; System.out.println("输入的两个数相除的结果是:" + c); } catch (IndexOutOfBoundsException | NumberFormatException | ArithmeticException e) { System.out.println("程序发生了数组越界、数字格式异常、算术异常之一!"); } catch (Exception e) { System.out.println("未知异常!"); e = new RuntimeException("未知异常!"); } } }
|
1-6 自定义异常
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 31 32 33 34 35 36 37 38 39
| import java.util.Scanner; import java.util.InputMismatchException;
class MyException extends Exception { public MyException() { super(); }
public MyException(String str) { super(str); } }
public class Test146 {
public static void main(String[] args) { int age; Scanner input = new Scanner(System.in); System.out.print("请输入您的年龄:"); try { age = input.nextInt(); if (age < 0) { throw new MyException("输入有误!年龄不能为负数~"); } else if (age > 120) { throw new MyException("输入有误!年龄不能大于120~"); } else { System.out.println("您输入的年龄为:" + age); } } catch (InputMismatchException e1) { System.out.println("您输入的年龄不是数字!"); } catch (MyException e2) { System.out.println(e2.getMessage()); } } }
|
1-7 验证用户名
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| import java.util.Scanner;
class LoginException extends Exception { public LoginException() { super(); }
public LoginException(String msg) { super(msg); } }
public class Test147 { public boolean validateLogin(String username, String pwd) { boolean con = false; boolean conUname = false; try { if (username.length() >= 6 && username.length() <= 10) { for (int i = 0; i < username.length(); i++) { char ch = username.charAt(i); if (ch >= '0' && ch <= '9') { conUname = true; } else { conUname = false; throw new LoginException("用户名不能包含非数字的字符!"); } } } else { throw new LoginException("用户名长度必须在6~10位之间!"); }
if (conUname) { if (pwd.length() == 6) { con = true; } else { con = false; throw new LoginException("密码长度必须是6位!"); } } } catch (LoginException e) { System.out.println(e.getMessage()); } return con; }
public static void main(String[] args) { Scanner input = new Scanner(System.in); System.out.print("用户名:"); String username = input.next(); System.out.print("密 码:"); String password = input.next(); Test147 lt = new Test147(); boolean con = lt.validateLogin(username, password); if (con) { System.out.println("用户名和密码输入成功!"); } } }
|
1-8 异常跟踪栈
- 异常跟踪栈
- 异常对象的printStackTrace()方法用于打印异常的跟踪栈信息。
- 根据输出结果可找到异常的源头并跟踪到异常一路触发的过程。
(1) printStackTrace
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
| class SelfException extends RuntimeException { SelfException() { }
SelfException(String msg) { super(msg); } }
public class Test148 { public static void main(String[] args) { firstMethod(); }
public static void firstMethod() { secondMethod(); }
public static void secondMethod() { thirdMethod(); }
public static void thirdMethod() { throw new SelfException("自定义异常信息!"); } }
|
(2) 多线程异常情况
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class Test149 implements Runnable { public void run() { firstMethod(); }
public void firstMethod() { secondMethod(); }
public void secondMethod() { int a = 5; int b = 0; int c = a / b; }
public static void main(String[] args) { new Thread(new Test149()).start(); } }
|
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
| import java.util.logging.Logger;
public class Test150 {
private static Logger log = Logger.getLogger(Test150.class.toString());
public static void main(String[] args) { log.finest("finest"); log.finer("finer"); log.fine("fine"); log.config("config"); log.info("info"); log.warning("warning"); log.severe("server"); } }
|
3 反射机制
- 反射机制
- 编译期是指把源码交给编译器编译成计算机可以执行的文件过程。
- Java中就是把代码编译成class文件的过程,编译期只做翻译功能。
- 运行期是把编译后的class文件给计算机执行,直到程序运行结束。
- Java反射机制在运行状态中
- 对于任意一个类,都能知道这个类的所有属性和方法(动态获取信息)。
- 对于任意一个对象,都能调用其任意方法和属性(动态调用对象方法)。
3-1 API
- API
- 实现Java反射机制的类都位于java.lang.reflect包中。
- 而java.lang.Class类是Java反射机制API中的核心类。
(1) java.lang.Class
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 31
| public class Test151 {
public static void main(String[] args) { Class clz1 = String.class; String str = "Hi~";
Class clz2 = str.getClass();
Class clz3 = int.class;
Class clz4 = Integer.class;
System.out.println(clz2.getName()); System.out.println(clz2.isInterface()); System.out.println(clz2.isArray()); System.out.println(clz2.getSuperclass().getName()); System.out.println(clz2.isPrimitive()); System.out.println(clz4.isPrimitive()); } }
|
(2) java.lang.reflect
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 31 32 33 34 35
| import java.lang.reflect.Method; import java.lang.reflect.Modifier;
public class Test152 {
public static void main(String[] args) { try { Class c = Class.forName("java.lang.String");
Method[] methods = c.getDeclaredMethods();
for (Method method : methods) { System.out.print(Modifier.toString(method.getModifiers()));
System.out.print(" " + method.getReturnType().getName() + " ");
System.out.println(method.getName() + "():"); } } catch (ClassNotFoundException e) { System.out.println("找不到指定类!"); } } }
|
3-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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| import java.lang.reflect.Constructor;
class Book1 { String name; int id, price;
private Book1() { }
protected Book1(String _name, int _id) { this.name = _name; this.id = _id; }
public Book1(String... strings) throws NumberFormatException { if (0 < strings.length) id = Integer.valueOf(strings[0]); if (1 < strings.length) price = Integer.valueOf(strings[1]); }
public void print() { System.out.println("name=" + name); System.out.println("id=" + id); System.out.println("price=" + price); } }
public class Test153 {
public static void main(String[] args) { Class book1 = Book1.class;
Constructor[] declaredConstructors = book1.getDeclaredConstructors();
for (int i = 0; i < declaredConstructors.length; i++) { Constructor con = declaredConstructors[i];
System.out.println("查看是否允许带有可变数量的参数:" + con.isVarArgs());
Class[] parameterTypes = con.getParameterTypes(); for (int j = 0; j < parameterTypes.length; j++) { System.out.println(parameterTypes[j]); }
Class[] exceptionTypes = con.getExceptionTypes(); for (int j = 0; j < exceptionTypes.length; j++) { System.out.print("该构造方法可能抛出的异常类型为:"); System.out.println(parameterTypes[j]); }
Book1 book2 = null; while (book2 == null) { try { if (i == 1) { book2 = (Book1) con.newInstance("Java", 10); } else if (i == 2) { book2 = (Book1) con.newInstance(); } else { Object[] parameters = new Object[] { new String[] { "100", "200" } }; book2 = (Book1) con.newInstance(parameters); } } catch (Exception e) { con.setAccessible(true); } } book2.print(); System.out.println("---------------------------------------------------------\n"); } } }
|
3-3 反射执行方法
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
| import java.lang.reflect.Method;
class Book2 { static void staticMethod() { System.out.println("执行staticMethod()方法"); }
public int publicMethod(int i) { System.out.println("执行publicMethod()方法"); return 100 + i; }
protected int protectedMethod(String s, int i) throws NumberFormatException { System.out.println("执行protectedMethod()方法"); return Integer.valueOf(s) + i; }
private String privateMethod(String... strings) { System.out.println("执行privateMethod()方法"); StringBuffer sb = new StringBuffer(); for (int i = 0; i < sb.length(); i++) { sb.append(strings[i]); } return sb.toString(); } }
public class Test154 {
public static void main(String[] args) { Book2 book = new Book2(); Class class2 = book.getClass();
Method[] declaredMethods = class2.getDeclaredMethods(); for (int i = 0; i < declaredMethods.length; i++) { Method method = declaredMethods[i]; System.out.println("获取到的方法具体名称:" + method.getName()); System.out.println("是否带可变数量的参数:" + method.isVarArgs());
System.out.print("方法的参数类型依次为:"); Class[] methodType = method.getParameterTypes(); for (int j = 0; j < methodType.length; j++) { System.out.println(methodType[j]); }
System.out.println("方法的返回值类型包含:" + method.getReturnType());
System.out.print("可能抛出的异常类型有:"); Class[] methodExceptions = method.getExceptionTypes(); for (int j = 0; j < methodExceptions.length; j++) { System.out.println(methodExceptions[j]); } boolean isTurn = true; while (isTurn) { try { isTurn = false; if (method.getName().equals("staticMethod")) { method.invoke(book); } else if (method.getName().equals("publicMethod")) { System.out.println("publicMethod(10)的返回值为:" + method.invoke(book, 10)); } else if (method.getName().equals("protectedMethod")) { System.out.println("protectedMethod(\"10\",15)的返回值为:" + method.invoke(book, "10", 15)); } else if (method.getName().equals("privateMethod")) { Object[] parameters = new Object[] { new String[] { "J", "A", "V", "A" } }; System.out.println("privateMethod()的返回值为:" + method.invoke(book, parameters)); } } catch (Exception e) { method.setAccessible(true); isTurn = true; } } System.out.println("---------------------------------------------------------\n"); } } }
|
3-4 访问成员变量
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| import java.lang.reflect.Field;
class Book3 { String name; public int id; private float price; protected boolean isLoan; }
public class Test155 {
public static void main(String[] args) { Book3 book3 = new Book3(); Class class3 = book3.getClass(); Field[] declaredFields = class3.getDeclaredFields(); for (int i = 0; i < declaredFields.length; i++) { Field field = declaredFields[i]; System.out.println("成员名称为:" + field.getName()); Class fieldType = field.getType(); System.out.println("成员类型为:" + fieldType); boolean isTurn = true; while (isTurn) { try { isTurn = false; System.out.println("改前成员值:" + field.get(book3)); if (fieldType.equals(int.class)) { System.out.println("利用setInt()方法修改成员的值"); field.setInt(book3, 100); } else if (fieldType.equals(float.class)) { System.out.println("利用setFloat()方法修改成员的值"); field.setFloat(book3, 29.815f); } else if (fieldType.equals(boolean.class)) { System.out.println("利用setBoolean()方法修改成员的值"); field.setBoolean(book3, true); } else { System.out.println("利用set()方法修改成员的值"); field.set(book3, "Java编程"); } System.out.println("改后成员值:" + field.get(book3)); } catch (Exception e) { field.setAccessible(true); isTurn = true; } } System.out.println("---------------------------------------------------------\n"); } } }
|
3-5 运用反射机制
- 运用反射机制
- 客户端如何调用服务器端HelloServiceImpl类中的echo()和getTime()方法?
- 把调用的方法名、参数类型、参数值及所属类名或接口名发送给服务器端。
- 再由服务器端调用相关对象的方法,最后,将方法的返回值发送给客户端。
- 为便于按面向对象的方式来处理客户端与服务器端的通信,把它们发送的信息用Call类表示。
- 一个Call对象表示客户端发起的一个远程调用,包括调用的接口名、参数类型、执行结果等。
- 这是一个网络程序,首先需要运行服务器端SimpleServer,然后再运行客户端SimpleClient。
javac SimpleServer.java && java SimpleServer
。
javac SimpleClient.java && java SimpleClient
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import java.util.Date;
interface HelloService { public String echo(String msg);
public Date getTime(); }
public class HelloServiceImpl implements HelloService { @Override public String echo(String msg) { return "echo:" + msg; }
@Override public Date getTime() { return new Date(); } }
|
(1) Call类的实现代码
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| import java.io.Serializable;
public class Call implements Serializable { private static final long serialVersionUID = 6659953547331194808L; private String className; private String methodName; private Class[] paramTypes; private Object[] params; private Object result;
public Call() { }
public Call(String className, String methodName, Class[] paramTypes, Object[] params) { this.className = className; this.methodName = methodName; this.paramTypes = paramTypes; this.params = params; }
public String getClassName() { return className; }
public void setClassName(String className) { this.className = className; }
public String getMethodName() { return methodName; }
public void setMethodName(String methodName) { this.methodName = methodName; }
public Class[] getParamTypes() { return paramTypes; }
public void setParamTypes(Class[] paramTypes) { this.paramTypes = paramTypes; }
public Object[] getParams() { return params; }
public void setParams(Object[] params) { this.params = params; }
public Object getResult() { return result; }
public void setResult(Object result) { this.result = result; }
public String toString() { return "className=" + className + "methodName=" + methodName; } }
|
(2) 客户端SimpleClient
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 31 32 33
| import java.io.*; import java.net.*;
public class SimpleClient { public void invoke() throws Exception { Socket socket = new Socket("localhost", 8000);
OutputStream out = socket.getOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(out);
InputStream in = socket.getInputStream(); ObjectInputStream ois = new ObjectInputStream(in);
Call call = new Call("ch12.HelloService", "echo", new Class[] { String.class }, new Object[] { "Java" });
oos.writeObject(call);
call = (Call) ois.readObject(); System.out.println(call.getResult());
ois.close(); oos.close(); socket.close(); }
public static void main(String args[]) throws Exception { new SimpleClient().invoke(); } }
|
(3) 服务端SimpleServer
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| import java.io.*; import java.net.*; import java.util.*; import java.lang.reflect.*;
public class SimpleServer { private Map remoteObjects = new HashMap();
public void register(String className, Object remoteObject) { remoteObjects.put(className, remoteObject); }
public void service() throws Exception { ServerSocket serverSocket = new ServerSocket(8000); System.out.println("服务器启动.");
while (true) { Socket socket = serverSocket.accept(); InputStream in = socket.getInputStream(); ObjectInputStream ois = new ObjectInputStream(in); OutputStream out = socket.getOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(out);
Call call = (Call) ois.readObject(); System.out.println(call);
call = invoke(call); oos.writeObject(call);
ois.close(); oos.close(); socket.close(); } }
public Call invoke(Call call) { Object result = null; try { String className = call.getClassName(); String methodName = call.getMethodName(); Object[] params = call.getParams(); Class classType = Class.forName(className); Class[] paramTypes = call.getParamTypes(); Method method = classType.getMethod(methodName, paramTypes);
Object remoteObject = remoteObjects.get(className);
if (remoteObject == null) { throw new Exception(className + "的远程对象不存在"); } else { result = method.invoke(remoteObject, params); } } catch (Exception e) { result = e; } call.setResult(result); return call; }
public static void main(String args[]) throws Exception { SimpleServer server = new SimpleServer();
server.register("ch13.HelloService", new HelloServiceImpl()); server.service(); } }
|
4 Java注解
- Java注解
- Java 5开始增加了对元数据(即注解:代码里的特殊标记)的支持,与注释有一定区别。
- 注解,Annotation,以@符号开头,不能改变程序的运行结果,也不会影响运行性能。
- 有些注解可以在编译时给用户提示或警告,有些则可以在运行时读写字节码文件信息。
- 作用:生成帮助文档、跟踪代码依赖性,实现替代配置文件功能、在编译时检查格式。
4-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 26
| class P1 { private String name = "钱三两"; private int age = 23;
@Override public String toString() { return name + ":" + age + "岁!"; } }
public class Test156 {
public static void main(String[] args) { P1 p1 = new P1(); System.out.println(p1); System.out.println(p1.toString()); } }
|
4-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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| @Deprecated class P2 { @Deprecated protected String name; private int age;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
@Deprecated public void setNameAndAge(String name, int age) { this.name = name; this.age = age; }
@Override public String toString() { return name + ":" + age + "岁!"; } }
public class Test157 {
public static void main(String[] args) { P2 p2 = new P2(); p2.setNameAndAge("钱三两", 23); p2.name = "赵五钱"; System.out.println(p2.toString()); } }
|
4-3 抑制编译器警告
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class Test158 { public static void main(String[] args) { display(10, 20, 30);
display("10", 20, 30); }
public static <T> void display(T... array) { for (T arg : array) { System.out.println(arg.getClass().getName() + ":" + arg); } } }
|
(1) @SafeVarargs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class Test159 {
public static void main(String[] args) { display(10, 20, 30);
display("10", 20, 30); }
@SafeVarargs public static <T> void display(T... array) { for (T arg : array) { System.out.println(arg.getClass().getName() + ":" + arg); } } }
|
(2) @SuppressWarnings
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Test160 {
@SuppressWarnings({ "deprecation" }) public static void main(String[] args) { P2 p3 = new P2(); p3.setNameAndAge("张小巧", 23); p3.name = "颜四六"; System.out.println(p3); } }
|
4-4 指定函数式接口
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 31 32 33 34 35 36 37 38 39
| @FunctionalInterface interface FunInterface { static void print() { System.out.println("Hello, World!"); }
default void show() { System.out.println("This is test."); }
void test();
}
public class Test161 {
public static void main(String[] args) { FunInterface fi = () -> System.out.println("Lambda implementation of test().");
fi.test();
fi.show();
FunInterface.print();
} }
|
4-5 Java元注解使用
- Java元注解使用
- Java 5定义了@Documented、@Target、@Retention、@Inherited。
- Java 8增加了@Repeatable、@Native,可在
java.lang.annotation
包中找到。
- @Native注解:表示该变量可以被本地代码引用,被代码生成工具使用,不常用。
- @Retention注解:用于描述注解的生命周期,也就是指该注解被保留的时间长短。
- @Retention注解的成员变量value,用来设置保留策略。
- 是
java.lang.annotation.RetentionPolicy
枚举类型。
- RetentionPolicy的3个枚举常量
- SOURCE(源文件保留)、CLASS(即class保留)、RUNTIME(运行时保留)。
- 生命周期排序:SOURCE < CLASS < RUNTIME ,前者能用后者定能用。
(1) @Target
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 31 32 33 34 35 36 37 38 39 40 41 42
| import java.lang.annotation.Target; import java.lang.reflect.Method; import java.lang.annotation.ElementType;
@Target({ ElementType.METHOD }) @interface MyTarget { }
public class Test162 {
@MyTarget public void annotatedMethod() { System.out.println("annotatedMethod被调用!"); }
public void normalMethod() { System.out.println("normalMethod被调用!"); }
public static void main(String[] args) throws Exception { Class<Test162> clazz = Test162.class;
for (Method method : clazz.getDeclaredMethods()) { if (method.isAnnotationPresent(MyTarget.class)) { System.out.println(method.getName() + "上存在@MyTarget注解!"); method.invoke(clazz.newInstance()); } else { System.out.println(method.getName() + "上不存在@MyTarget注解!"); } } } }
|
(2) @Inherited
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 31
| import java.lang.annotation.Target; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.ElementType; import java.lang.annotation.RetentionPolicy;
@Target({ ElementType.TYPE }) @Inherited @Retention(RetentionPolicy.RUNTIME) @interface MyInherited { }
@MyInherited public class Test163 {
public static void main(String[] args) { System.out.println(Test163.class.getAnnotation(MyInherited.class)); System.out.println(TestB.class.getAnnotation(MyInherited.class)); System.out.println(TestC.class.getAnnotation(MyInherited.class)); } }
class TestB extends Test163 { }
class TestC extends TestB { }
|
(3) @Repeatable
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 31 32 33 34 35 36 37 38 39 40 41 42 43
| import java.lang.reflect.Method; import java.lang.annotation.Retention; import java.lang.annotation.Repeatable; import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME) @interface Roles { Role[] value(); }
@Retention(RetentionPolicy.RUNTIME) @Repeatable(Roles.class) @interface Role { String roleName(); }
public class Test164 {
@Role(roleName = "role1") @Role(roleName = "role2") public String doString() { return "测试"; }
public static void main(String[] args) throws NoSuchMethodException { Method method = Test164.class.getDeclaredMethod("doString");
Role[] roles = method.getAnnotationsByType(Role.class);
System.out.println("获取的Role注解数量:" + roles.length); for (Role role : roles) { System.out.println("Role名称:" + role.roleName()); } } }
|
(4) @Documented
- 文件编译:
javac Test165.java
。
- 生成文档:
javadoc -d doc Test165.java
。
- 若命令执行报错“错误: 编码GBK的不可映射字符”。
- 文件编译:
javac -encoding UTF-8 Test165.java
。
- 生产文档:
javadoc -encoding UTF-8 -docencoding UTF-8 -charset UTF-8 -d doc Test165.java
。
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| import java.lang.reflect.Method; import java.lang.annotation.Target; import java.lang.annotation.Retention; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.RetentionPolicy;
@Documented
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME) @interface MyDocumented { String value() default "@Documented注解"; }
public class Test165 {
@MyDocumented("测试自定义注解") public String test() { return "测试"; }
public static void main(String[] args) { try { Class<Test165> clazz = Test165.class;
Method method = clazz.getDeclaredMethod("test");
if (method.isAnnotationPresent(MyDocumented.class)) { MyDocumented annotation = method.getAnnotation(MyDocumented.class); System.out.println("方法test在@MyDocumented注解上的值:" + annotation.value()); } else { System.out.println("方法test在@MyDocumented注解上没有值!"); } } catch (Exception e) { e.printStackTrace(); } } }
|
4-6 Java自定义注解
- Java自定义注解
- 声明自定义注解使用@interface关键字实现,定义注解与定义接口很像。
- 默认情况下注解可在程序的任何地方使用,修饰类、接口、方法和变量等。
- 注解前面的访问修饰符和类一样都有两种:公有访问权限、默认访问权限。
- 一个源程序文件中可声明多个注解,但只能有一个是公有访问权限的注解。
- 并且源程序文件命名和公有访问权限的注解名需要保持一致。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
public @interface MyMarker {}
public @interface MyTag { String name(); }
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface SomeMetaAnnotation {}
|
(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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| import java.lang.reflect.Method; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
@interface MyTag1 { String name();
int age(); }
public class Test166 { @MyTag1(name = "钱三两", age = 23) public void info() { }
public static void main(String[] args) { try { Class<Test166> clazz = Test166.class;
Method method = clazz.getMethod("info");
if (method.isAnnotationPresent(MyTag1.class)) { MyTag1 annotation = method.getAnnotation(MyTag1.class);
System.out.println("姓名:" + annotation.name()); System.out.println("年龄:" + annotation.age()); } else { System.out.println("info方法没有使用MyTag1注解!"); } } catch (NoSuchMethodException e) { e.printStackTrace(); } } }
|
(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 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| import java.lang.reflect.Method; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
@interface MyTag2 { String name() default "张三丰";
int age() default 27; }
public class Test167 { @MyTag2 public void info() { }
public static void main(String[] args) { try { Class<Test167> clazz = Test167.class;
Method method = clazz.getMethod("info");
if (method.isAnnotationPresent(MyTag2.class)) { MyTag2 annotation = method.getAnnotation(MyTag2.class);
System.out.println("姓名:" + annotation.name()); System.out.println("年龄:" + annotation.age()); } else { System.out.println("info方法没有使用MyTag2注解!"); } } catch (NoSuchMethodException e) { e.printStackTrace(); } } }
|
5 Java I/O流
- Java I/O流
- 流是一组有序的数据序列,即将数据从一个地方带到另一个地方。
- Java程序通过流来完成输入输出,所有输入输出都以流形式处理。
- 数据流是Java进行I/O操作的对象,按不同标准可分成不同的类别。
- 按流方向分:输入流、输出流。
- 按数据单位:字节流、字符流。
- 按功能分类:节点流、处理流。
5-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
| import java.io.IOException;
public class Test168 {
public static void main(String[] args) { byte[] byteData = new byte[100]; System.out.print("请输入英文:"); try { System.in.read(byteData); } catch (IOException e) { e.printStackTrace(); }
System.out.print("输入内容为:"); for (int i = 0; i < byteData.length; i++) { System.out.print((char) byteData[i]); } } }
|
5-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.File; import java.io.OutputStream; import java.io.FileOutputStream;
public class Test169 {
public static void main(String[] args) throws Exception { System.out.println("系统默认编码:" + System.getProperty("file.encoding"));
File f = new File("./files" + File.separator + "Test169.txt");
OutputStream out = new FileOutputStream(f);
byte b[] = "通过ISO8859-1进行编码转换".getBytes("ISO8859-1");
out.write(b);
out.close(); } }
|
5-3 文件操作类
- 文件操作类
- Java中,File类是java.io包中唯一代表磁盘文件本身的对象。
- File类不能访问文件内容本身,需使用输入输出流才能访问。
(1) 获取文件属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import java.io.File; import java.util.Date;
public class Test170 { public static void main(String[] args) { String path = "./files/"; File f = new File(path, "Test169.txt"); System.out.println("是否可读:" + (f.canRead() ? "可读" : "不可读")); System.out.println("是否可写:" + (f.canWrite() ? "可写" : "不可写")); System.out.println("文件目录:" + (f.isFile() ? "文件" : "非文件")); System.out.println("文件目录:" + (f.isDirectory() ? "目录" : "非目录")); System.out.println("是否隐藏:" + (f.isHidden() ? "隐藏" : "非隐藏")); System.out.println("文件长度:" + f.length() + "字节"); System.out.println("文件名称:" + f.getName()); System.out.println("文件路径:" + f.getPath()); System.out.println("绝对路径:" + f.getAbsolutePath()); System.out.println("最后修改:" + new Date(f.lastModified())); } }
|
(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
| import java.io.File; import java.io.IOException;
public class Test171 {
public static void main(String[] args) throws IOException {
String path = "./files" + File.separator + "Test171.txt"; File f = new File(path);
if (f.exists()) { f.delete(); } f.createNewFile(); } }
|
(3) 创建删除目录
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import java.io.File;
public class Test172 { public static void main(String[] args) { String path = "./test"; File f = new File(path); if (f.exists()) { f.delete(); } f.mkdir(); } }
|
(4) 遍历目录功能
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| import java.io.File; import java.io.FilenameFilter;
class ImageFilter implements FilenameFilter { @Override public boolean accept(File dir, String name) { return name.endsWith(".sys") || name.endsWith(".txt"); } }
public class Test173 {
public static void main(String[] args) { File f = new File("C:");
String fileList[] = f.list();
String fileLists[] = f.list(new ImageFilter());
System.out.printf("%-26s %-8s %-10s%n", "文件名称", "文件类型", "文件大小"); System.out.println("----------------------------------------------------------"); for (int i = 0; i < fileList.length; i++) { File file = new File(f, fileList[i]); String type = file.isFile() ? "文件" : "目录"; long size = file.length(); System.out.printf("%-30s %-10s %d字节%n", fileList[i], type, size); }
System.out.println("----------------------------------------------------------"); for (int i = 0; i < fileLists.length; i++) { File file = new File(f, fileLists[i]); String type = file.isFile() ? "文件" : "目录"; long size = file.length(); System.out.printf("%-30s %-10s %d字节%n", fileLists[i], type, size); } } }
|
5-4 字节流使用
- 字节流使用
- 字节输入流:InputStream类及其子类的对象表示字节输入流,常用子类如下。
- FileInputStream类:从文件中读取数据。
- ObjectInputStream类:将对象反序列化。
- SequenceInputStream类:将多个字节输入流串联成一个字节输入流。
- PipedInputStream类:连接到一个PipedOutputStream(管道输出流)。
- ByteArrayInputStream类:将字节数组转换为字节输入流,从中读取字节。
- 字节输出流:OutputStream类及其子类的对象表示字节输出流,常用子类如下。
- FileOutputStream类:向文件中写数据。
- ObjectOutputStream类:将对象序列化。
- ByteArrayOutputStream类:向内存缓冲区的字节数组中写数据。
- PipedOutputStream类:连接到一个PipedlntputStream(管道输入流)。
(1) 字节数组输入流
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import java.io.ByteArrayInputStream;
public class Test174 {
public static void main(String[] args) { byte[] b = new byte[] { 13, -1, 25, -9, -5, 23 }; ByteArrayInputStream bais = new ByteArrayInputStream(b, 0, 6); int i = bais.read(); while (i != -1) { System.out.println("原值:" + (byte) i + "\t\t转换为int类型:" + i); i = bais.read(); } } }
|
(2) 字节数组输出流
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import java.util.Arrays; import java.io.ByteArrayOutputStream;
public class Test175 {
public static void main(String[] args) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] b = new byte[] { 13, -1, 25, -9, -5, 23 }; baos.write(b, 0, 6); System.out.println("数组共包含的字节数:" + baos.size() + "字节"); byte[] newByteArray = baos.toByteArray(); System.out.println(Arrays.toString(newByteArray)); } }
|
(3) 字节文件输入流
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 31 32 33 34 35 36 37 38 39 40
| import java.io.File; import java.io.IOException; import java.io.FileInputStream;
public class Test176 {
public static void main(String[] args) { File f = new File("./Test175.java"); FileInputStream fis = null; try { fis = new FileInputStream(f); byte[] bytes = new byte[1024]; int n = 0; System.out.println("文件内容如下:"); while ((n = fis.read(bytes)) != -1) { String s = new String(bytes, 0, n); System.out.println(s); } } catch (Exception e) { e.printStackTrace(); } finally { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } }
|
(4) 字节文件输出流
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| import java.io.File; import java.io.IOException; import java.io.FileInputStream; import java.io.FileOutputStream;
public class Test177 {
public static void main(String[] args) { FileInputStream fis = null; FileOutputStream fos = null; try { File srcFile = new File("./Test176.java"); fis = new FileInputStream(srcFile); File targetFile = new File("./files/Test176.txt"); fos = new FileOutputStream(targetFile); byte[] bytes = new byte[1024]; int i = fis.read(bytes); while (i != -1) { fos.write(bytes, 0, i); i = fis.read(bytes); } System.out.println("写入结束啦!"); } catch (Exception e) { e.printStackTrace(); } finally { try { fis.close(); fos.close(); } catch (IOException e) { e.printStackTrace(); } } } }
|
5-5 字符流使用
- 字符流使用
- 字符输入流:Reader类是所有字符流输入类的父类,常用子类如下。
- PipedReader类:连接到一个PipedWriter。
- BufferedReader类:为其他字符输入流提供读缓冲区。
- StringReader类:将字符串转换为字符输入流,从中读取字符。
- CharArrayReader类:将字符数组转换为字符输入流,从中读取字符。
- InputStreamReader类:将字节输入流转换为字符输入流,可指定字符编码。
- 字符输出流:Writer类是所有字符输出流的父类,常用子类如下。
- PipedWriter类:连接到一个PipedReader。
- BufferedWriter类:为其他字符输出流提供写缓冲区。
- CharArrayWriter类:向内存缓冲区的字符数组写数据。
- StringWriter类:向内存缓冲区的字符串StringBuffer写数据。
- OutputStreamReader类:将字节输出流转换为字符输出流,可指定字符编码。
(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 26 27 28 29 30 31
| import java.io.FileReader; import java.io.IOException;
public class Test178 {
public static void main(String[] args) { FileReader fr = null; try { fr = new FileReader("./Test177.java"); int i = 0; System.out.println("文件内容如下:"); while ((i = fr.read()) != -1) { System.out.print((char) i); } } catch (Exception e) { System.out.print(e); } finally { try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } }
|
(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 31 32 33 34 35 36
| import java.util.Scanner; import java.io.FileWriter; import java.io.IOException;
public class Test179 {
public static void main(String[] args) { Scanner input = new Scanner(System.in); FileWriter fw = null; try { fw = new FileWriter("./files/Test179.txt"); for (int i = 0; i < 4; i++) { System.out.print("请输入第" + (i + 1) + "个字符串:"); String name = input.next(); fw.write(name + "\r\n"); } System.out.println("录入完成啦!"); } catch (Exception e) { System.out.println(e.getMessage()); } finally { try { fw.close(); } catch (IOException e) { e.printStackTrace(); } } } }
|
(3) 字符缓冲区输入
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 31 32 33 34 35 36 37 38 39
| import java.io.FileReader; import java.io.IOException; import java.io.BufferedReader; import java.io.FileNotFoundException;
public class Test180 {
public static void main(String[] args) { FileReader fr = null; BufferedReader br = null; try { fr = new FileReader("./Test179.java"); br = new BufferedReader(fr); System.out.println("文件内容如下:"); String strLine = ""; while ((strLine = br.readLine()) != null) { System.out.println(strLine); } } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e2) { e2.printStackTrace(); } finally { try { fr.close(); br.close(); } catch (IOException e) { e.printStackTrace(); } } } }
|
(4) 字符缓冲区输出
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 31 32 33 34 35 36 37 38 39 40 41
| import java.util.Scanner; import java.io.FileWriter; import java.io.IOException; import java.io.BufferedWriter;
public class Test181 {
public static void main(String[] args) { Scanner input = new Scanner(System.in); BufferedWriter bw = null; try { bw = new BufferedWriter(new FileWriter("./files/Test181.txt")); for (int i = 0; i < 4; i++) { System.out.print("请输入第" + (i + 1) + "个字符串:"); String name = input.next(); bw.write(name); bw.newLine(); } bw.flush(); System.out.println("录入完成啦!"); } catch (Exception e) { System.out.println(e.getMessage()); } finally { try { if (bw != null) { bw.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
|
5-6 转换流使用
- 转换流使用
- 正常情况下字节流可以对所有的数据进行操作。
- 但是在处理一些文本时用到字符流会更加方便。
- Java IO流提供了两种用于将字节流转换为字符流的转换流。
- InputStreamReader用于将字节输入流转换为字符输入流。
- OutputStreamWriter用于将字节输出流转换为字符输出流。
(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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| import java.io.IOException; import java.io.FileInputStream; import java.io.InputStreamReader; import java.io.FileNotFoundException;
public class Test182 { public static void main(String[] args) {
try { FileInputStream fis = new FileInputStream("./files/Test181.txt"); InputStreamReader isr = new InputStreamReader(fis, "UTF-8"); int b = 0; while ((b = isr.read()) != -1) { System.out.print((char) b); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
|
(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 31 32 33
| import java.io.IOException; import java.io.BufferedReader; import java.io.InputStreamReader;
public class Test183 { public static void main(String[] args) { try { InputStreamReader reader = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(reader); String line = null;
while (true) { System.out.print("请输入内容:"); line = br.readLine();
if (line == null) { break; } if (line.equals("exit")) { System.exit(0); } System.out.println("输入内容为:" + line); } } catch (IOException e) { e.printStackTrace(); } } }
|
5-7 图书的存储
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| import java.util.List; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.io.BufferedReader;
class Book { private int no; private String name; private double price;
public Book(int no, String name, double price) { this.no = no; this.name = name; this.price = price; }
public String toString() { return "图书编号:" + this.no + ",图书名称:" + this.name + ",图书单价:" + this.price + "\n"; }
public static void write(List books) { FileWriter fw = null; try { fw = new FileWriter("./files/books.txt"); for (int i = 0; i < books.size(); i++) { fw.write(books.get(i).toString()); } } catch (Exception e) { System.out.println(e.getMessage()); } finally { try { fw.close(); } catch (IOException e) { e.printStackTrace(); } } }
public static void read() { FileReader fr = null; BufferedReader br = null; try { fr = new FileReader("./files/books.txt"); br = new BufferedReader(fr); String str = ""; while ((str = br.readLine()) != null) { System.out.println(str); } } catch (Exception e) { System.out.println(e.getMessage()); } finally { try { br.close(); fr.close(); } catch (IOException e) { e.printStackTrace(); } } } }
public class Test184 { public static void main(String[] args) { Book b1 = new Book(1001, "康熙的红票", 25.9); Book b2 = new Book(1002, "挪威的森林", 32.5); List books = new ArrayList(); books.add(b1); books.add(b2); Book.write(books); System.out.print("----------------------"); System.out.print("图书信息"); System.out.print("----------------------\n"); Book.read(); } }
|