java异常处理和对象序列化和内部类

部分来源于蓝桥杯学习
有风险的行为

  • 当我们调用了一个不是自己写的方法,我们必须要认识到该方法是有风险的,所以要及时处理
try{
//正常运行代码
}catch(有风险的行为){
//风险处理
}

如果try中的代码的确发生了异常,则程序 不再执行try中异常之后的代码,而是直接跳到cath中执行

  • 运行时异常:代码在编辑(编译阶段)时 不报错,运行时才报错。语法上, 可以选择性处理。
  • 检查异常:代码在编辑(编译阶段)时报错。在编辑时,必须处理。
  • throws:抛出异常,方法可以抓住其他方法抛出的异常
//有异常的方法
 public static void test04() throws NullPointerException,ClassNotFoundException{//抛出异常,抛出给上级(方法调用处)
            Object obj = null   ;
            obj.equals("") ;//空指针
            Class.forName("xxx") ;
    }
//
    public static void main(String[] args) throws Exception{//继续往上抛出异常(JVM)
            test04();//异常
    }

异常是个对象
java异常处理和对象序列化和内部类_第1张图片

  • throw:声明异常,jdk中自带了很多类型的异常,但如果 这些内置的异常 仍然不能满足项目的需求,那么就需要创建 自定义异常。
//public class MyException  extends  Throwable{
//public class MyException  extends  NullPointerException{
public class MyException  extends  Exception{//推荐
    public MyException(String message){//异常信息
        super(message);
    }
}
public class Demo03 {
//
    public static void main(String[] args)   {
        int age = 188 ;
        //约定,年龄不能大于120
        if(age<= 0 || age>120){
            try {
                //手工声明一个异常
                throw new MyException("年龄不能大于120");
            }catch ( MyException e ){
                e.printStackTrace();
                System.out.println(e.getMessage());
            }
        }
    }
}

java异常处理和对象序列化和内部类_第2张图片

public class FullConstructors {
  public static void f() throws MyException {
    System.out.println("Throwing MyException from f()");
    throw new MyException();
  }
  public static void g() throws MyException {
    System.out.println("Throwing MyException from g()");
    throw new MyException("Originated in g()");
  }
  public static void main(String[] args) {
    try {
      f();
    } catch(MyException e) {
      e.printStackTrace(System.out);
    }
    try {
      g();
    } catch(MyException e) {
      e.printStackTrace(System.out);//发送到System.out
    }
  }
} /* Output:
Throwing MyException from f()
MyException
        at FullConstructors.f(FullConstructors.java:11)
        at FullConstructors.main(FullConstructors.java:19)
Throwing MyException from g()
MyException: Originated in g()
        at FullConstructors.g(FullConstructors.java:15)
        at FullConstructors.main(FullConstructors.java:24)
*///:~

异常的方法

import static net.mindview.util.Print.*;
//
public class ExceptionMethods {
  public static void main(String[] args) {
    try {
      throw new Exception("My Exception");
    } catch(Exception e) {
      print("Caught Exception");
      print("getMessage():" + e.getMessage());
      print("getLocalizedMessage():" +
        e.getLocalizedMessage());
      print("toString():" + e);
      print("printStackTrace():");
      e.printStackTrace(System.out);
    }
  }
} /* Output:
Caught Exception
getMessage():My Exception
getLocalizedMessage():My Exception
toString():java.lang.Exception: My Exception
printStackTrace():
java.lang.Exception: My Exception
        at ExceptionMethods.main(ExceptionMethods.java:8)
*///:~

栈轨迹
printStackTrace()方法所提供的信息可以通过getStackTrace()访问,将返回一个由栈轨迹中元素构成的数组

public class WhoCalled {
  static void f() {
    // Generate an exception to fill in the stack trace
    try {
      throw new Exception();
    } catch (Exception e) {
      for(StackTraceElement ste : e.getStackTrace())
        System.out.println(ste.getMethodName());//打印方法名
    }
  }
  static void g() { f(); }
  static void h() { g(); }
  public static void main(String[] args) {
    f();
    System.out.println("--------------------------------");
    g();
    System.out.println("--------------------------------");
    h();
  }
} /* Output:
f
main
--------------------------------
f
g
main
--------------------------------
f
g
h
main
*///:~

重新抛出异常

public class Rethrowing {
  public static void f() throws Exception {
    System.out.println("originating the exception in f()");
    throw new Exception("thrown from f()");
  }
  public static void g() throws Exception {
    try {
      f();
    } catch(Exception e) {
      System.out.println("Inside g(),e.printStackTrace()");
      e.printStackTrace(System.out);
      throw e;
    }
  }
  public static void h() throws Exception {
    try {
      f();
    } catch(Exception e) {
      System.out.println("Inside h(),e.printStackTrace()");
      e.printStackTrace(System.out);
      throw (Exception)e.fillInStackTrace();  //更新异常信息
    }
  }
  public static void main(String[] args) {
    try {
      g();
    } catch(Exception e) {
      System.out.println("main: printStackTrace()");
      e.printStackTrace(System.out);
    }
    try {
      h();
    } catch(Exception e) {
      System.out.println("main: printStackTrace()");
      e.printStackTrace(System.out);
    }
  }
} /* Output:
originating the exception in f()
Inside g(),e.printStackTrace()
java.lang.Exception: thrown from f()
        at Rethrowing.f(Rethrowing.java:7)
        at Rethrowing.g(Rethrowing.java:11)
        at Rethrowing.main(Rethrowing.java:29)
main: printStackTrace()      //两次调用printStackTrace 第二次是原来的
java.lang.Exception: thrown from f()
        at Rethrowing.f(Rethrowing.java:7)
        at Rethrowing.g(Rethrowing.java:11)
        at Rethrowing.main(Rethrowing.java:29)
originating the exception in f()
Inside h(),e.printStackTrace()
java.lang.Exception: thrown from f()
        at Rethrowing.f(Rethrowing.java:7)
        at Rethrowing.h(Rethrowing.java:20)
        at Rethrowing.main(Rethrowing.java:35)
main: printStackTrace()
java.lang.Exception: thrown from f()  //回到重新抛出异常的地方
        at Rethrowing.h(Rethrowing.java:24)
        at Rethrowing.main(Rethrowing.java:35)
*///:~
class OneException extends Exception {
  public OneException(String s) { super(s); }
}
//
class TwoException extends Exception {
  public TwoException(String s) { super(s); }
}
//
public class RethrowNew {
  public static void f() throws OneException {
    System.out.println("originating the exception in f()");
    throw new OneException("thrown from f()");
  }
  public static void main(String[] args) {
    try {
      try {
        f();
      } catch(OneException e) {
        System.out.println(
          "Caught in inner try, e.printStackTrace()");
        e.printStackTrace(System.out);
        throw new TwoException("from inner try");
      }
    } catch(TwoException e) {
      System.out.println(
        "Caught in outer try, e.printStackTrace()");
      e.printStackTrace(System.out);
    }
  }
} /* Output:
originating the exception in f()
Caught in inner try, e.printStackTrace()
OneException: thrown from f()
        at RethrowNew.f(RethrowNew.java:15)
        at RethrowNew.main(RethrowNew.java:20)
Caught in outer try, e.printStackTrace()
TwoException: from inner try  //最后异常只知道自己来自main
        at RethrowNew.main(RethrowNew.java:25)
*///:~

finally
无论正常,还是异常,始终都会执行的代码
不论执行完try,还是执行完catch,最终都会执行finally的代码
1.即使遇到return ,也仍然会执行finally
2.除非虚拟机关闭,才不会执行finally

对象序列化

如果要储存或恢复对象的状态,需要对象的序列化
将序列化对象写入文件

//创建文件FileOutputStream
FileOutputStream fileStram=new FileOutputStream("a.txt");
//链接对象流与文件
ObjectOutputStream os=new ObjectOutputStream(fileStream);
//
os.writeObject(CharacterOne);
os.writeObject(Charactertwo);

os.close();
  • FileOutputStream把字节写入文件,ObjectOutputStream将对象转成可以写入的数据
  • 如果要让类能够序列化,就要实现Serializable,Serializable接口称为marker或tag类的标记用接口,此接口无任何方法需要实现
  • 如果某实例变量不能或不该被序列化就把他标记为transient(瞬时)。
    解序列化
//创建文件FileInputStream
FileInputStream fileStram=new FileInputStream("a.txt");
//链接对象流与文件
ObjectOutputStream os=new ObjectInputStream(fileStream);
//每次读取一个对象,多了则抛出异常
Object one =os.readObject();
Object two=os.readObject();

os.close();

//

package serializable;
import java.io.*;
public class GameCharacter implements Serializable{
	int power;
	String type;
	String[] weapons;
	//
	 public GameCharacter(int p,String t,String[] w) {
		power=p;
		type=t;
		weapons=w;
	//
}
//
	public int getPower() {
		return power;
	}
	public String getType() {
		return type;
	}
	public String getWeapons() {
		String weaponList="";
		for(int i=0;i<weapons.length;i++)
			weaponList+=weapons[i]+" ";
		return weaponList;
	}
}

package serializable;
//
import java.io.*;
//
public class GameSaverTest {
public static void main(String[] args) {
	GameCharacter one=new GameCharacter(50,"elf",new String[] {"bow","sword","dust"});
	GameCharacter two=new GameCharacter(60,"elf1",new String[] {"bow1","sword1","dust1"});
	GameCharacter three=new GameCharacter(70,"elf",new String[] {"bow2","sword2","dust2"});
	try {
		ObjectOutputStream os=new ObjectOutputStream(new FileOutputStream("Game.ser"));
		os.writeObject(one);
		os.writeObject(two);
		os.writeObject(three);
		os.close();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	one=null;
	two=null;
	three=null;
	try {
		ObjectInputStream is=new ObjectInputStream(new FileInputStream("Game.ser"));
		GameCharacter oneRestore=(GameCharacter) is.readObject();//对象顺序读入
		GameCharacter twoRestore=(GameCharacter) is.readObject();//对象顺序读入
		GameCharacter threeRestore=(GameCharacter) is.readObject();//对象顺序读入
		System.out.println("one's type"+oneRestore.getType());
		System.out.println("two's type"+twoRestore.getType());
		System.out.println("three's type"+threeRestore.getType());
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
}

File.class

package serializable;
//
import java.io.*;
//
public class ReadAFile {
public static void main(String[] args) {
	File myFile=new File("Foo.txt");
	try {
		//字符连接文本文件串流
		FileReader fileReader=new FileReader(myFile);
		//缓冲区
		BufferedReader reader=new BufferedReader(fileReader);
		
		String line=null;
		while((line=reader.readLine())!=null) {
			System.out.println(line);
		}
	} catch (FileNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
}
package serializable;
import java.io.*;
public class WriteAFile {
public static void main(String[] args) {
	//以字符串的方式写入
	try {
		FileWriter writer=new FileWriter("Foo.txt");
		writer.write("hello foo!");
		writer.close();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
}

序列化的控制
如果不希望对象的某一部分被序列化,或者该对象还原后,子对象需要重新创建,可以通过实现Externalizable接口,这个接口继承自Serializable,并多了两个方法writeExternal(),和readExternal();

当对象序列化时,会调用writeExternal()方法,在对象恢复时,会调用对象的构造器(如果构造器不是public,则在恢复对象时会有异常),然后再执行readExternal()方法。

import java.io.*;
import static net.mindview.util.Print.*;
//
public class Blip3 implements Externalizable {
  private int i;
  private String s; // No initialization
  public Blip3() {
    print("Blip3 Constructor");
    // s, i not initialized
  }
  public Blip3(String x, int a) {
    print("Blip3(String x, int a)");
    s = x;
    i = a;
    // s & i initialized only in non-default constructor.
  }
  public String toString() { return s + i; }
  public void writeExternal(ObjectOutput out)
  throws IOException {
    print("Blip3.writeExternal");
    // You must do this:
    out.writeObject(s);
    out.writeInt(i);
  }
  public void readExternal(ObjectInput in)
  throws IOException, ClassNotFoundException {
    print("Blip3.readExternal");
    // You must do this:
    s = (String)in.readObject();
    i = in.readInt();
  }
  public static void main(String[] args)
  throws IOException, ClassNotFoundException {
    print("Constructing objects:");
    Blip3 b3 = new Blip3("A String ", 47);
    print(b3);
    ObjectOutputStream o = new ObjectOutputStream(
      new FileOutputStream("Blip3.out"));
    print("Saving object:");
    o.writeObject(b3);//调用实现的方法
    o.close();
    // Now get it back:
    ObjectInputStream in = new ObjectInputStream(
      new FileInputStream("Blip3.out"));
    print("Recovering b3:");
    b3 = (Blip3)in.readObject();
    print(b3);//调用实现的方法
  }
} /* Output:
Constructing objects:
Blip3(String x, int a)
A String 47
Saving object:
Blip3.writeExternal
Recovering b3:
Blip3 Constructor
Blip3.readExternal
A String 47
*///:~

transient
transient修饰的变量不会被序列化。

内部类

内部类:存在于一个类的内部的类被称为内部类,内部类分为:静态类、成员类、局部类、匿名类

静态类

作为类的静态成员的内部类称为静态类。
静态类可以引用外部类的静态成员,但不能引用非静态成员变量。
在未创建外部类的情况下可以直接创建静态类对象

class Outer{
	static int a=10;
	int b=20;
	static void f(){
	     System.out .println("hi~~");
	}
	static class Inner{
		int c=30;
		public void g(){
		      f();
		      System.out.println(a+""+c);
		}	
	}
}
public class M{
	public static void main(String[]args){
	    Outer.Inner ob=new Outer.Inner();
	    ob.g();
	}
}

成员类
作为非静态成员的内部类。
只有创建了外部类对象,才能创建成员类对象
成员类可以引用外部类的所有成员

class Outer{
	static int a=10;
	int b=20;
	void f(){
		System.out.println("hi~~");
	}
	class Inner{
		int c=30;
		public void g(){
		    b=100;
		    f();
		    System.out.println(a+""+c);
		}
	}
}
public class M {
	public static void main(String[]args){
		Outer out=new Outer();
		Outer.Inner in=out.new Inner();
		in.g();
		System.out.println(out.b);
	}
}

可以在外部内的非静态成员变量中创建成员类的对象。
成员类内部的成员不能有static成员,但允许有静态常量存在。

class Outer{
	void f(){
		Inner in=new Inner();
		System.out.println(in.a);
	}
	class Inner{
		int a=100;
	}
}
public class Member {
	public static void main(String[]args){
		Outer out=new Outer();
		out.f();
	}
}

输出 100;
匿名类
匿名类是为唯一对象而定义的类:new 父类构造方法(){匿名类体}。
匿名类是某个类的子类,且类体不允许出现static类型的成员

abstract class Speak
{  public abstract void speakHello();
}
class Student
{  void f(Speak sp)
   { 
        sp.speakHello();
   }
}
public class M
{ 
     public static void main(String args[]){ 
         Student st=new Student();
         st.f( new Speak()
    	   {
    	       public void speakHello(){ 
                System.out.println("I am a student, how are you");
           }
    	   } );
         Speak speak= new Speak()
         { 
    	      public void speakHello(){  
                System.out.println("大家好,祝工作顺利!");
	      }
         };
       speak.speakHello();
    }
}

你可能感兴趣的:(笔记)