部分来源于蓝桥杯学习
有风险的行为
try{
//正常运行代码
}catch(有风险的行为){
//风险处理
}
如果try中的代码的确发生了异常,则程序 不再执行try中异常之后的代码,而是直接跳到cath中执行
//有异常的方法
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();//异常
}
//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());
}
}
}
}
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();
//创建文件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();
}
}