Java程序设计题

构造有限个数的有效三角形

`/*创建一个三角形类,包含属性:private int a,b,c;分别代表三角形的三条边。设计是需要满足如下需求:  
a. 在创建对象输入三条边,三边取值必须合法(三边均为正值,且任意两边之和大于第三边),否则将无法创建对象;
b.为使类更易于维护,必须单独设计一个boolean limit(…)函数,实现对三条边的限制检查,符合创建条件则返回真,否则返回假。
c.该类有一个public boolean setEdges(int x, int y, int z)方法(注:此方法为非静态方法),将a/b/c的值替换成x/y/z,返回true。
但当x,y,z的值不满足三角形限制条件时,将不予替换,并返回false;
d. 三角形至多能创建3个。
设计该三角形类,并验证上述需求。 */
public class Triangle {
    private int a,b,c;
    static int total = 3,count = 0;
    private Triangle(int x,int y,int z){
        a = x;b = y;c = z;
        count++;
    }
    static boolean limit(int x,int y,int z) {
        if(x>0 && y>0 && z>0 && x+y>z && x+z>y && y+z>x) {
            return true;
        }
        return false;
    }
    public static Triangle setTri(int x,int y,int z) {
        if(limit(x,y,z) && count

注:

  1. count++要放在构造函数中,只要调用了构造函数就会创建对象
  2. 类中的toString()方法必须用public修饰,不能改小权限,且该方法会被对象自动调用
  3. 静态方法只能使用类中的静态成员,所以limit()方法和total,count变量要为静态的

形状识别器

使用抽象类实现

`/*实现智能识别器,可针对圆形、矩形、三角形、梯形不同形状,提供如下服务:
a. 识别形状的面积;
b. 输出形状属性信息:类型和各种参数,如:梯形,上底:20,下底:30,高:10)--- 考虑toString()*/
import static java.lang.Math.PI;
abstract class Shape {
    private String type;
    Shape(String t){
        type  = t;
    }
    String getType() {
        return type;
    }
    abstract double getArea();
}
class Circle extends Shape{
    private int  r;
    Circle(String s,int R){
        super(s);
        r = R;
    }
    double getArea() {
        return PI*r*r;
    }
    public String toString() {
        return "半径:" + r;
    }
}
class Rectangle extends Shape{
    private int w,h;
    Rectangle(String s,int x,int y){
        super(s);
        w = x;h = y;
    }
    double getArea() {
        return w*h;
    }
    public String toString() {
        return "宽:" + w + ",高:" + h;
    }
}
class Trigon extends Shape{
    private int  s,h;
    Trigon(String t,int x,int y){
        super(t);
        s = x;h = y;
    }
    double getArea() {
        return s*h/2;
    }
    public String toString() {
        return "底:" + s + ",高:" + h;
    }
}
class Trapezoidal extends Shape{
    private int  a,b,h;
    Trapezoidal(String s,int x,int y,int z){
        super(s);
        a = x;b = y;h = z;
    }
    double getArea() {
        return (a+b)*h/2;
    }
    public String toString() {
        return "上底:" + a + ",下底:" + b + ",高:" + h;
    }
}
class Recognizer{
    public static void identify(Shape s) {
        System.out.println(s.getType() + "," + s.toString() + ",面积:" + s.getArea());
    }
}
class App2{
    public static void main(String[] args) {
        Shape[] s = {new Circle("圆形", 2),
                new Rectangle("矩形", 3, 4),
                new Trigon("三角形", 4, 2),
                new Trapezoidal("梯形", 2, 4, 3)
        };
        for(int i = 0;i<4;i++)
            Recognizer.identify(s[i]);
    }
}` 

*   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

注:

  1. 私有属性可以通过类中的方法返回得到
  2. abstract类中不一定要有抽象方法,但抽象方法所属类一定是抽象类
  3. 抽象方法不能有方法体
  4. 该识别器基于超类编程,实现即插即用的功能,添加子类很方便

使用接口实现

`/*【接口实现】实现智能识别器,可针对圆形、矩形、三角形、梯形不同形状,提供如下服务:
a. 识别形状的面积;
b. 输出形状属性信息:类型和各种参数,如:梯形,上底:20,下底:30,高:10)--- 考虑toString()*/
import static java.lang.Math.PI;
interface Shapein {
    public abstract String getType();
    public abstract double getArea();
}
class yx implements Shapein{
    private int  r;
    private String type;
    yx(String s,int R){
        r = R;
        type = s;
    }
    public String getType() {
        return type;
    }
    public double getArea() {
        return PI*r*r;
    }
    public String toString() {
        return "半径:" + r;
    }
}
class jx implements Shapein{
    private int w,h;
    private String type;
    jx(String s,int x,int y){
        w = x;h = y;
        type = s;
    }
    public String getType() {
        return type;
    }
    public double getArea() {
        return w*h;
    }
    public String toString() {
        return "宽:" + w + ",高:" + h;
    }
}
class sj implements Shapein{
    private int w,h;
    private String type;
    sj(String s,int x,int y){
        w = x;h = y;
        type = s;
    }
    public String getType() {
        return type;
    }
    public double getArea() {
        return w*h/2;
    }
    public String toString() {
        return "底:" + w + ",高:" + h;
    }
}
class tx implements Shapein{
    private int a,b,h;
    private String type;
    tx(String s,int x,int y,int z){
        a = x;b = y;h = z;
        type = s;
    }
    public String getType() {
        return type;
    }
    public double getArea() {
        return (a+b)*h/2;
    }
    public String toString() {
        return "上底:" + a + ",下底:" + b + ",高:" + h;
    }
}
class Identifier{
    public static void identify(Shapein s) {
        System.out.println(s.getType() + "," + s.toString() + ",面积:" + s.getArea());
    }
}
class App3{
    public static void main(String[] args) {
        Shapein[] s = {new yx("圆形", 2),
                new jx("矩形", 3, 4),
                new sj("三角形", 4, 2),
                new tx("梯形", 2, 4, 3)
        };
        for(int i = 0;i<4;i++)
            Identifier.identify(s[i]);
    }
}` 

*   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

注:

  1. 接口中只能定义常量,且常量都有public static final修饰,接口中的方法都有public abstract修饰
  2. 在main函数中,用的是接口引用指向实现类的对象,Java在利用接口变量调用其实现类的对象的方法时,该方法必须已经在接口中被声明,而且实现类的对象对该方法进行了重写。

兵种游戏设计

`/*兵种包括轰炸机、直升机、重型坦克、轻型坦克、音波坦克、步兵、飞行兵
b.轰炸机、直升机、飞行兵属于空军;步兵、轻型坦克、重型坦克属于陆军,音波坦克属于水陆两栖;
c.轻型坦克、步兵只能攻击陆军,音波坦克只能攻击空军,轰炸机可攻击陆军、海军;重型坦克可攻击陆军、空军,直升机、飞行兵可攻击海军、陆军、空军;
并验证设计效果。(即向兵种变量填入海/陆/空军兵种,检测a.attack(b)的输出)*/
interface 陆军{}
interface 空军{}
interface 海军{}
interface 可攻击陆军{
    default void attack(陆军 x) {System.out.println("可攻击陆军");}
}
interface 可攻击空军{
    default void attack(空军 x) {System.out.println("可攻击空军");}
}
interface 可攻击海军{
    default void attack(海军 x) {System.out.println("可攻击海军");}
}
interface 可攻击陆军海军 extends 可攻击陆军,可攻击海军{}
interface 可攻击陆军空军 extends 可攻击陆军,可攻击空军{}
interface 可攻击陆军空军海军 extends 可攻击陆军,可攻击空军,可攻击海军{}
abstract class 兵种{
    private String type;
    public String getType() {return type;}
    兵种(String x){
        type = x;
    }
    public abstract void attack(兵种 x);
    public String attackinfo(兵种 x) {
        return getType() + "遇见" + x.getType() +":";
    }
}
class 轰炸机 extends 兵种 implements 空军,可攻击陆军海军{
    轰炸机(){
        super("轰炸机");
    }
    public void attack(兵种 x) {
        if(x instanceof 陆军) {
            System.out.print(attackinfo(x));
            attack((陆军)x);
        }else if(x instanceof 海军) {
            System.out.print(attackinfo(x));
            attack((海军)x);
        }else {
            System.out.println(attackinfo(x) + "不能攻击!");
        }
    }
}
class 直升机 extends 兵种 implements 空军,可攻击陆军空军海军{
    直升机(){
        super("直升机");
    }
    public void attack(兵种 x) {
        if(x instanceof 陆军) {
            System.out.print(attackinfo(x));
            attack((陆军)x);
        }else if(x instanceof 海军) {
            System.out.print(attackinfo(x));
            attack((海军)x);
        }else {
            System.out.print(attackinfo(x));
            attack((空军)x);
        }
    }
}
class 飞行兵 extends 兵种 implements 空军,可攻击陆军空军海军{
    飞行兵(){
        super("飞行兵");
    }
    public void attack(兵种 x) {
        if(x instanceof 陆军) {
            System.out.print(attackinfo(x));
            attack((陆军)x);
        }else if(x instanceof 海军) {
            System.out.print(attackinfo(x));
            attack((海军)x);
        }else {
            System.out.print(attackinfo(x));
            attack((空军)x);
        }
    }
}
class 重型坦克 extends 兵种 implements 陆军,可攻击陆军空军{
    重型坦克(){
        super("重型坦克");
    }
    public void attack(兵种 x) {
        if(x instanceof 陆军) {
            System.out.print(attackinfo(x));
            attack((陆军)x);
        }else if(x instanceof 空军) {
            System.out.print(attackinfo(x));
            attack((空军)x);
        }else {
            System.out.println(attackinfo(x) + "不能攻击!");
        }
    }
}
class 音波坦克 extends 兵种 implements 陆军,海军,可攻击空军{
    音波坦克(){
        super("音波坦克");
    }
    public void attack(兵种 x) {
        if(x instanceof 空军) {
            System.out.print(attackinfo(x));
            attack((空军)x);
        }else {
            System.out.println(attackinfo(x) + "不能攻击!");
        }
    }
}
class 轻型坦克 extends 兵种 implements 陆军,可攻击陆军{
    轻型坦克(){
        super("轻型坦克");
    }
    public void attack(兵种 x) {
        if(x instanceof 陆军) {
            System.out.print(attackinfo(x));
            attack((陆军)x);
        }else {
            System.out.println(attackinfo(x) + "不能攻击!");
        }
    }
}
class 步兵 extends 兵种 implements 陆军,可攻击陆军{
    步兵(){
        super("步兵");
    }
    public void attack(兵种 x) {
        if(x instanceof 陆军) {
            System.out.print(attackinfo(x));
            attack((陆军)x);
        }else {
            System.out.println(attackinfo(x) + "不能攻击!");
        }
    }
}
class App4{
    public static void main(String[] args) {
        兵种[] x = {
                new 轰炸机(),new 直升机(),new 重型坦克(),new 轻型坦克(),new 音波坦克(),new 飞行兵(),new 步兵()
        };
        for(int i = 0;i

注:

  1. 陆军、海军和空军都是空接口,仅起到标签作用
  2. 接口中的attack()方法不是抽象方法,有缺省实现,子类可以不重写
  3. 通过instanceof来判断兵种的具体类型,并在attack()中进行强制类型转换

PCI

`/*展示接口实现“功能扩展”
【需求】主板预留PCI插槽。不可能知道该插槽将插装什么硬件。
主板做的事情只能是:加电、启动、run、停止。主板类预留5个PCI插槽,如何实现?
提示:5个插槽,就是5个变量。
 * */
interface PCI {
    void start();
    void run();
    void stop();
}
class NetCard implements PCI{
    public void start() {System.out.print("n网卡启动  ");}
    public void run() {System.out.print("网卡运行");}
    public void stop() {System.out.print("n网卡停止");}
}
class SoundCard implements PCI{
    public void start() {System.out.print("n声卡启动  ");}
    public void run() {System.out.print("声卡运行");}
    public void stop() {System.out.print("n声卡停止");}
}
class DisplayCard implements PCI{
    public void start() {System.out.print("n显卡启动  ");}
    public void run() {System.out.print("显卡运行");}
    public void stop() {System.out.print("n显卡停止");}
}
class MainBoard{
    PCI[] pci = new PCI[5];
    public void add(PCI x) {
        for(int i = 0;i

互斥

`/*线程类T定义方式为:class T implements Runnable{ int data; ...}
线程体实现依次输出data的1~10倍数据。
在main中,构造和启动线程的方式形如: T t=new T(2);  t.start(); 
构造data分别为2、3、5的线程,线程名分别为t2、t3、t5,要求:t2、t3、t5分3行输出,且输出结果不得交叉。
 * */
class D{
    int x;
}
class T implements Runnable {
    D d;
    int data;
    Thread t;
    T(int x,D y){
        data = x;
        d = y;
        t = new Thread(this);
    }
    public void run() {
        synchronized(d) {
            for(int i = 1;i<=10;i++) {
                System.out.print(data*i + " ");
            }
            System.out.println();
        }
    }
    void join() {
        try {t.join();}catch(Exception e) {;}
    }
    void start() {
        t.start();
    }
}
class App6{
    public static void main(String[] args) {
        System.out.println("main线程开始");
        D d = new D();
        T t2 = new T(2,d);
        T t3 = new T(3,d);
        T t5 = new T(5,d);
        t2.start();t3.start();t5.start();
        t2.join();t3.join();t5.join();
        System.out.println("main线程结束");
    }
}` 

*   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

注:

  1. 类D仅用来充当对象锁和共享资源,所以不同线程传入的D要相同
  2. 该程序中join()用于让main线程在t2、t3和t5线程结束后结束
  3. t2、t3和t5并不是线程对象,但其内部包含线程对象

同步

`/*线程类T定义方式为:class T implements Runnable{ int data; ...}
线程体实现依次输出data的1~10倍数据。
在main中,构造和启动线程的方式形如: T t=new T(2);  t.start(); 
构造data分别为2、3、5的线程,线程名分别为t2、t3、t5,要求:t2、t3、t5输出结果按2 3 5 4 6 10...特定顺序输出。
 * */
class Flag{
    private int flag = 0;
    void ChangeFlag(int x,int y) {
        while(flag!=x) try {wait();}catch(Exception e) {;}
        flag = y;notifyAll();
    }
}
class Th implements Runnable{
    private Flag flag;
    int data,x,y;
    Thread t;
    Th(int h,int m,int n,Flag f){
        t = new Thread(this);
        data = h;flag = f;x = m;y = n;
    }
    public void run() {
        synchronized(flag) {
            for(int i = 1;i<=10;i++) {
                try {Thread.sleep(1000);}catch(Exception e) {}
                flag.ChangeFlag(x, y);
                System.out.print(data*i + " ");
            }
        }
    }
    void start() {t.start();}
}
class App7{
    public static void main(String[] args) {
        Flag f = new Flag();
        Th t2 = new Th(2,0,1,f);
        Th t3 = new Th(3,1,2,f);
        Th t5 = new Th(5,2,0,f);
        t2.start();t3.start();t5.start();
    }
}` 

*   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

注:

  1. Flag类用于状态标志不同线程的执行顺序,如果轮到t2执行,则将状态改为下一个执行线程的状态,并唤醒所有线程,否则等待
  2. 判断标志时不能用if,因为可能会存在伪唤醒,放在循环体中可避免这种情形
  3. 线程定义中的构造函数需要传入四个值:要进行操作的数据、当前状态、下一个状态、共享资源

委托事件处理模型

`/*做一个简单的计算器,[1][+][2]=[3],[]为文本框,点击=按钮计算出结果,最后一个文本框不可点击(enable(false)),并借助标签显示出错信息
 * a.当操作数文本框/运算符文本框中的字符串,在剔除首尾空格后,若字符串长度为0,则抛出自定义异常NoneException,提示“操作数为空”/“运算符为空”
 * b.当运算符框中的字符串s剔除首尾空格(s.trim())后,若包含多个字符/不是+-* /等字符时抛出自定义异常OpCharException,提示“运算符过多”/“无法识别的运算符”
 * c.对Double.parseDouble(s),如果无法将s转换成正确的double值,若s是“1.2.3”、“a.b”、“a3b”或是转换后的数值越界时,将抛出非检查型异常NumberFormatException,
 * 提示“数据格式有错”;产生除零错时将抛出非检查型异常ArithmeticException,提示“除零错”
*/
import java.awt.*;import java.awt.event.*;import javax.swing.*;
class NoneException extends Exception{
    public NoneException(String msg){super(msg);}
}
class OpCharException extends Exception{
    public OpCharException(String msg){super(msg);}
}
public class GUI extends JFrame implements ActionListener {
    private JTextField op1,op2,opchar,result;//对应操作数1、2、操作符、运算结果
    private JButton bt_eq;//=按钮
    private JLabel t_la;//显示错误信息
    public GUI(){
        super("计算器");
        setSize(500,100);
        setLocation(500,500);
        setLayout(new FlowLayout());        
        op1 = new JTextField(5); add(op1);
        opchar = new JTextField(2); add(opchar);
        op2 = new JTextField(5); add(op2);
        bt_eq = new JButton("="); add(bt_eq);
        result = new JTextField(5);
        result.setEnabled(false);
        add(result);
        t_la = new JLabel(" ");
        add(t_la);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置点击关闭按钮
        bt_eq.addActionListener(this);
    }
    private double getDouble(JTextField jf,int num) throws NoneException{
        //检测jf是否为合法的操作数
        String s = jf.getText().trim();double val;
        if(s.length() == 0) throw new NoneException("第"+ num + "个操作数为空");
        try {
            val = Double.parseDouble(s);
        }catch(NumberFormatException e) {
            throw new NumberFormatException("第"+ num + "个操作数格式有错");
        }
        return val;
    }
    private char getOpChar(JTextField jf) throws NoneException,OpCharException{
        //检测jf是否为合法的运算符
        String s = jf.getText().trim();
        if(s.length()==0) throw new NoneException("运算符为空");
        if(s.length()>1) throw new OpCharException("运算符过多");
        if("+-*/".indexOf(s)<0) throw new OpCharException("无法识别的运算符");
        return s.charAt(0);//返回字符串第0位置的字符
    }
    private double compute(double a,double b,char op) {
        //进行运算
        if(b==0 && op == '/') throw new ArithmeticException("除零错");
        if(op == '+') return a+b;
        if(op == '-') return a-b;
        if(op == '*') return a*b;
        if(op == '/') return a/b;
        return -1;//实际上为通过编译而设置
    }
    public void actionPerformed(ActionEvent e) {
        double x,y;
        char z;
//        if(e.getCommand() == bt_eq) {
        if(e.getActionCommand().equals("=")) {//确定事件源的两种写法
            try {
                x = getDouble(op1,1);y = getDouble(op2,2);z = getOpChar(opchar);
                result.setText(compute(x,y,z)+"");
            }
            catch(Exception c) {
                result.setText(" ");
                t_la.setText(c.getMessage());
            }
        }
    }
}
class App8{
    public static void main(String[] args) {new GUI();}
}` 

*   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

注:

  1. 自定义异常类必须是Throwable类的子类,一般以Exception作为超类,且可以通过super()将出错信息传给超类,Exception类也可以通过getMessage()方法显示出错信息
  2. 委托事件处理模型:

    • 处理者(GUI对象)要实现ActionListener接口
    • 类中要重写接口中的actionPerformed()方法,方法中的参数为ActionEvent,在该方法中执行处理过程
    • 将事件源(bt_eq按钮)与处理者相关联(通过addActionListener()方法)
  3. 将处理过程分成多个部分,使处理过程更加清晰
  4. “± /”.indexOf(s)返回的是指定子字符串s在字符串"±/"中第一次出现处的索引

复制文件

逐个字符读/写文件

`public class FileCopy {
    public static void main(String[] args) {
        File inF = new File("a.txt");//关联当前文件夹中的文件a.txt,作为读出源头
        File outF = new File("b.txt");//关联当前文件夹中的文件b.txt,作为写入目标
        try {
            int ch;
            FileReader in = new FileReader(inF);//建立阅读器对象in
            FileWriter out = new FileWriter(outF);
            System.out.println("文件开始复制");
            while((ch = in.read())!=-1)
                out.write(ch);//从流in中读取字符ch并写入流out
            in.close();out.close();//关闭流,释放相关资源
            System.out.println("文件复制结束");
        }catch(FileNotFoundException e) {
            System.out.println("文件未找到!n" + e);
        }catch(IOException e) {
            System.out.println("File read error!n" + e);
        }
    }
}` 

*   1
*   2
*   3
*   4
*   5
*   6
*   7
*   8
*   9
*   10
*   11
*   12
*   13
*   14
*   15
*   16
*   17
*   18
*   19
*   20

注:

  1. a.txt要和src放在同一目录下,否则会找不到文件,当然也可以用绝对路径

按字符流整体读/写文件

`public class FileCopy {
    public static void main(String[] args) {
        File inF = new File("a.txt");
        File outF = new File("c.txt");
        char[] ca = new char[(int)inF.length()];
        try {
            FileReader in = new FileReader(inF);
            FileWriter out = new FileWriter(outF);
            System.out.println("文件开始复制");
            in.read(ca);out.write(ca);
            in.close();out.close();
            System.out.println("文件复制结束");
        }catch(FileNotFoundException e) {
            System.out.println("文件未找到!n" + e);
        }catch(IOException e) {
            System.out.println("File read error!n" + e);
        }
    }
}` 

*   1
*   2
*   3
*   4
*   5
*   6
*   7
*   8
*   9
*   10
*   11
*   12
*   13
*   14
*   15
*   16
*   17
*   18
*   19

基于缓冲区读/写文件

`public class FileCopy {
    public static void main(String[] args) {
        String s;
        File inF = new File("a.txt");
        File outF = new File("d.txt");
        try {
            FileReader in = new FileReader(inF);
            FileWriter out = new FileWriter(outF);
            BufferedReader br = new BufferedReader(in);
            BufferedWriter bw = new BufferedWriter(out);
            System.out.println("文件开始复制");
            while((s = br.readLine()) !=null) {//读取一行,并赋值给字符串s
                bw.write(s,0,s.length());//将s中从0至s.length()的所有字符串写入bw
                bw.newLine();//添加行分隔符
            }
            br.close();bw.close();
            System.out.println("文件复制结束");
        }catch(FileNotFoundException e) {
            System.out.println("文件未找到!n" + e);
        }catch(IOException e) {
            System.out.println("File read error!n" + e);
        }
    }
}` 

*   1
*   2
*   3
*   4
*   5
*   6
*   7
*   8
*   9
*   10
*   11
*   12
*   13
*   14
*   15
*   16
*   17
*   18
*   19
*   20
*   21
*   22
*   23
*   24

防止出现乱码

`class Utf_8_to_GBK {
    public static void main(String args[] ){
         BufferedReader br=null; 
         BufferedWriter bw=null; 
         String s;
        try{  //按UTF-8格式读,按GBK格式写
            br=new BufferedReader(new InputStreamReader(new FileInputStream("a.txt"), "UTF-8")); 
            bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("e.txt"), "GBK")); 
            System.out.println("文件开始复制");
            while((s=br.readLine())!=null){
                bw.write(s,0,s.length());
                bw.newLine(); 
            }
            br.close(); bw.close();
            System.out.println("文件复制结束");
         }
         catch(UnsupportedEncodingException e){ System.out.println("不支持的编码格式!n"+e); }
         catch(FileNotFoundException e){ System.out.println("文件没找到!n"+e); }
         catch(IOException e){ System.out.println("File read error!n"+e); }
    }
}` 

*   1
*   2
*   3
*   4
*   5
*   6
*   7
*   8
*   9
*   10
*   11
*   12
*   13
*   14
*   15
*   16
*   17
*   18
*   19
*   20
*   21

序列化与反序列化

`import java.io.*;
class C{
    public int x;
}
class B{
    public int x;
    public C c;
    public B(int n,C c1) {x = n;c = c1;}
}
class A implements Serializable{
    int x; 
    transient B b;//b引用对象将不被序列化
}
class ReadObject{
    public static void main(String[] args) {
        C c = new C();A a =new A();a.x = 10;a.b = new B(5,c);
        System.out.println("序列化前 a.b.x=" + a.b.x);
        A new_a = null;
        try {
            FileOutputStream fo = new FileOutputStream("serialObj.bat");
            ObjectOutputStream obj_o = new ObjectOutputStream(fo);
            obj_o.writeObject(a);obj_o.close();
            FileInputStream fi = new FileInputStream("serialObj.bat");
            ObjectInputStream obj_i = new ObjectInputStream(fi);
            new_a = (A)obj_i.readObject();obj_i.close();
        }catch(Exception e) {e.printStackTrace();}
        System.out.print("恢复对象 new_a.b.x=" + new_a.b.x);
    }
}` 

*   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

注:

  1. 本例将产生空指针异常,因为未对B对象序列化,在恢复时就没有创建相应的对象,当引用该属性域时会出错
  2. transient是成员修饰符,不能修饰类

你可能感兴趣的:(java)