• 87.java基础4面向对象下


    51.单例的另一种方式:

    final:最终的
    1.可以用来修饰:类、方法、变量
    2.具体的:
    2.1 final 用来修饰一个类:此类不能被其他类所继承。
     *          比如:String类、System类、StringBuffer类
    2.2 final 用来修饰方法:表明此方法不可以被重写
     * 			比如:Object类中getClass();
    2.3 final 用来修饰变量:此时的"变量"就称为是一个常量
     * 	    1. final修饰属性:可以考虑赋值的位置:显式初始化、代码块中初始化、构造器中初始化
     * 	    2. final修饰局部变量:
     *        尤其是使用final修饰形参时,表明此形参是一个常量。当我们调用此方法时,给常量形参赋一个实参。一旦赋值以后,就只能在方法体内使用此形参,但不能进行重新赋值。
    static final 用来修饰属性:全局常量
    

    52.abstract关键字

    package com.atguigu.java;
    /*
     * abstract关键字的使用
     * 1.abstract:抽象的
     * 2.abstract可以用来修饰的结构:类、方法
     * 3. abstract修饰类:抽象类
     * 		> 此类不能实例化
     *      > 抽象类中一定有构造器,便于子类实例化时调用(涉及:子类对象实例化的全过程)
     *      > 开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作
     * 4. abstract修饰方法:抽象方法
     * 		> 抽象方法只有方法的声明,没有方法体
     * 		> 包含抽象方法的类,一定是一个抽象类。反之,抽象类中可以没有抽象方法的。
     *      > 若子类重写了父类中的所有的抽象方法后,此子类方可实例化
     *        若子类没有重写父类中的所有的抽象方法,则此子类也是一个抽象类,需要使用abstract修饰
     
     * abstract使用上的注意点:
     * 1.abstract不能用来修饰:属性、构造器等结构 
     * 2.abstract不能用来修饰私有方法、静态方法、final的方法、final的类
     */
    public class AbstractTest {
    	public static void main(String[] args) {
    		
    		//一旦Person类抽象了,就不可实例化
    //		Person p1 = new Person();
    //		p1.eat();		
    	}
    }
    abstract class Creature{
    	public abstract void breath();
    }
    abstract class Person extends Creature{
    	String name;
    	int age;	
    	public Person(){		
    	}
    	public Person(String name,int age){
    		this.name = name;
    		this.age = age;
    	}	
    	//不是抽象方法:
    //	public void eat(){
    //		
    //	}
    	//抽象方法
    	public abstract void eat();	
    	public void walk(){
    		System.out.println("人走路");
    	}		
    }
    class Student extends Person{	
    	public Student(String name,int age){
    		super(name,age);
    	}
    	public Student(){
    	}	
    	public void eat(){
    		System.out.println("学生多吃有营养的食物");
    	}
    	@Override
    	public void breath() {
    		System.out.println("学生应该呼吸新鲜的没有雾霾的空气");
    	}
    }
    
    问题:
    	1.问什么抽象类不可以使用final关键字声明?
         因为抽象类希望被子类继承,final修饰的类不可以被继承
         2.一个抽象类中可以定义构造器么?
         可以
         
    

    53.抽象类的匿名子类

    package com.atguigu.java;
    /*
     * 抽象类的匿名子类
     */
    public class PersonTest {	
    	public static void main(String[] args) {		
    		method(new Student());//匿名对象(对象没有名称直接实例化)		
    		Worker worker = new Worker();
    		method1(worker);//非匿名的类非匿名的对象(可以知道对象是由哪个类实例化的,也进行赋值worker)	 
    		method1(new Worker());//非匿名的类匿名的对象		
    		System.out.println("********************");		
    		//创建了一匿名子类的对象:p
    		Person p = new Person(){   //由于Person是抽象类,不能实例化,但是通过显式的重写的抽象方法,所以叫做(匿名子类对象)
    			@Override
    			public void eat() {
    				System.out.println("吃东西");
    			}
    			@Override
    			public void breath() {
    				System.out.println("好好呼吸");
    			}			
    		};
    		
    		method1(p);
    		System.out.println("********************");
    		//创建匿名子类的匿名对象
    		method1(new Person(){
    			@Override
    			public void eat() {
    				System.out.println("吃好吃东西");
    			}
    			@Override
    			public void breath() {
    				System.out.println("好好呼吸新鲜空气");
    			}
    		});
    	}	
    	public static void method1(Person p){
    		p.eat();
    		p.breath();
    	}	
    	public static void method(Student s){		
    	}
    }
    class Worker extends Person{  ///其中Person是一个抽象类
    	@Override
    	public void eat() {
    	}
    	@Override
    	public void breath() {
    	}	
    }
    ---------------------------------------------抽象类模板类设计模式1--------------------------------------
    package com.atguigu.java;
    /*
     * 抽象类的应用:模板方法的设计模式
     * 
     */
    public class TemplateTest {
    	public static void main(String[] args) {		
    		SubTemplate t = new SubTemplate();		
    		t.spendTime();
    	}
    }
    abstract class Template{	
    	//计算某段代码执行所需要花费的时间
    	public void spendTime(){		
    		long start = System.currentTimeMillis();		
    		this.code();//不确定的部分、易变的部分		
    		long end = System.currentTimeMillis();		
    		System.out.println("花费的时间为:" + (end - start));		
    	}	
    	public abstract void code();		
    }
    class SubTemplate extends Template{
    	@Override
    	public void code() {		
    		for(int i = 2;i <= 1000;i++){
    			boolean isFlag = true;
    			for(int j = 2;j <= Math.sqrt(i);j++){
    				
    				if(i % j == 0){
    					isFlag = false;
    					break;
    				}
    			}
    			if(isFlag){
    				System.out.println(i);
    			}
    		}
    	}	
    }
    ------------------------------------------抽象类模板类设计模式2-----------------------------------------
    package com.atguigu.java;
    //抽象类的应用:模板方法的设计模式
    public class TemplateMethodTest {
    
    	public static void main(String[] args) {
    		BankTemplateMethod btm = new DrawMoney();
    		btm.process();
    		BankTemplateMethod btm2 = new ManageMoney();
    		btm2.process();
    	}
    }
    abstract class BankTemplateMethod {
    	// 具体方法
    	public void takeNumber() {
    		System.out.println("取号排队");
    	}
    	public abstract void transact(); // 办理具体的业务 //钩子方法
    	public void evaluate() {
    		System.out.println("反馈评分");
    	}
    	// 模板方法,把基本操作组合到一起,子类一般不能重写
    	public final void process() {
    		this.takeNumber();
    		this.transact();// 像个钩子,具体执行时,挂哪个子类,就执行哪个子类的实现代码
    		this.evaluate();
    	}
    }
    class DrawMoney extends BankTemplateMethod {
    	public void transact() {
    		System.out.println("我要取款!!!");
    	}
    }
    class ManageMoney extends BankTemplateMethod {
    	public void transact() {
    		System.out.println("我要理财!我这里有2000万美元!!");
    	}
    }
    

    54.final说明:

    http://10.20.85.121:8080/test_path/1k.html
    

    55.java接口:

    package com.atguigu.java1;
    /*
     * 接口的使用
     * 1.接口使用interface来定义
     * 2.Java中,接口和类是并列的两个结构
     * 3.如何定义接口:定义接口中的成员 		
     * 		3.1 JDK7及以前:只能定义全局常量和抽象方法
     * 			>全局常量:public static final的.但是书写时,可以省略不写
     * 			>抽象方法:public abstract的		
     * 		3.2 JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法(略)
     * 4. 接口中不能定义构造器的!意味着接口不可以实例化
     * 5. Java开发中,接口通过让类去实现(implements)的方式来使用.
     *    如果实现类覆盖了接口中的所有抽象方法,则此实现类就可以实例化
     *    如果实现类没有覆盖接口中所有的抽象方法,则此实现类仍为一个抽象类
     * 6. Java类可以实现多个接口   --->弥补了Java单继承性的局限性
     *   格式:class AA extends BB implements CC,DD,EE
     * 7. 接口与接口之间可以继承,而且可以多继承
     * *******************************
     * 8. 接口的具体使用,体现多态性
     * 9. 接口,实际上可以看做是一种规范
     * 面试题:抽象类与接口有哪些异同?
     */
    public class InterfaceTest {
    	public static void main(String[] args) {
    		System.out.println(Flyable.MAX_SPEED);
    		System.out.println(Flyable.MIN_SPEED);
    //		Flyable.MIN_SPEED = 2;	
    		Plane plane = new Plane();
    		plane.fly();
    	}}
    interface Flyable{
    	//全局常量
    	public static final int MAX_SPEED = 7900;//第一宇宙速度
    	int MIN_SPEED = 1;//省略了public static final
    	//抽象方法
    	public abstract void fly();
    	//省略了public abstract
    	void stop();	
    	//Interfaces cannot have constructors
    //	public Flyable(){
    //		
    //	}
    }
    interface Attackable{
    	void attack();	
    }
    class Plane implements Flyable{
    	@Override
    	public void fly() {
    		System.out.println("通过引擎起飞");
    	}
    	@Override
    	public void stop() {
    		System.out.println("驾驶员减速停止");
    	}	
    }
    abstract class Kite implements Flyable{
    	@Override
    	public void fly() {	
    	}	
    }
    class Bullet extends Object implements Flyable,Attackable,CC{
    	@Override
    	public void attack() {
    		// TODO Auto-generated method stub	
    	}
    	@Override
    	public void fly() {
    		// TODO Auto-generated method stub		
    	}
    	@Override
    	public void stop() {
    		// TODO Auto-generated method stub	
    	}
    	@Override
    	public void method1() {
    		// TODO Auto-generated method stub	
    	}
    	@Override
    	public void method2() {
    		// TODO Auto-generated method stub		
    	}	
    }
    //************************************
    interface AA{
    	void method1();
    }
    interface BB{	
    	void method2();
    }
    interface CC extends AA,BB{
    }
    
    

    56.接口多态实现:

    package com.atguigu.java1;
    /*
     * 接口的使用
     * 1.接口使用上也满足多态性
     * 2.接口,实际上就是定义了一种规范
     * 3.开发中,体会面向接口编程!
     */
    public class USBTest {
    	public static void main(String[] args) {	
    		Computer com = new Computer();
    		//1.创建了接口的非匿名实现类的非匿名对象
    		Flash flash = new Flash();
    		com.transferData(flash);		
    		//2. 创建了接口的非匿名实现类的匿名对象
    		com.transferData(new Printer());		
    		//3. 创建了接口的匿名实现类的非匿名对象
    		USB phone = new USB(){
    			@Override
    			public void start() {
    				System.out.println("手机开始工作");
    			}
    			@Override
    			public void stop() {
    				System.out.println("手机结束工作");
    			}			
    		};
    		com.transferData(phone);		
    		//4. 创建了接口的匿名实现类的匿名对象		
    		com.transferData(new USB(){
    			@Override
    			public void start() {
    				System.out.println("mp3开始工作");
    			}
    			@Override
    			public void stop() {
    				System.out.println("mp3结束工作");
    			}
    		});
    	}
    }
    class Computer{	
    	public void transferData(USB usb){//USB usb = new Flash();
    		usb.start();		
    		System.out.println("具体传输数据的细节");		
    		usb.stop();
    	}	
    }
    interface USB{
    	//常量:定义了长、宽、最大最小的传输速度等	
    	void start();	
    	void stop();	
    }
    class Flash implements USB{
    	@Override
    	public void start() {
    		System.out.println("U盘开启工作");
    	}
    	@Override
    	public void stop() {
    		System.out.println("U盘结束工作");
    	}	
    }
    
    class Printer implements USB{
    	@Override
    	public void start() {
    		System.out.println("打印机开启工作");
    	}
    	@Override
    	public void stop() {
    		System.out.println("打印机结束工作");
    	}	
    }
    

    57.java接口实现代理类:

    package com.atguigu.java1;
    /*
     * 接口的应用:代理模式
     */
    public class NetWorkTest {
    	public static void main(String[] args) {
    		Server server = new Server();
    //		server.browse();
    		ProxyServer proxyServer = new ProxyServer(server);		
    		proxyServer.browse();		
    	}
    }
    interface NetWork{	
    	public void browse();	
    }
    //被代理类
    class Server implements NetWork{
    	@Override
    	public void browse() {
    		System.out.println("真实的服务器访问网络");
    	}
    }
    //代理类
    class ProxyServer implements NetWork{
    	
    	private NetWork work;
    	
    	public ProxyServer(NetWork work){
    		this.work = work;
    	}	
    	public void check(){
    		System.out.println("联网之前的检查工作");
    	}	
    	@Override
    	public void browse() {
    		check();
    		
    		work.browse();		
    	}	
    }
    

    58.java接口练习题:

    package com.atguigu.exer3;
    /*
     * interface CompareObject{
    	public int compareTo(Object o);   
    	//若返回值是 0 , 代表相等; 若为正数,代表当前对象大;负数代表当前对象小
     }
    
     */
    public interface CompareObject {
    	//若返回值是 0 , 代表相等; 若为正数,代表当前对象大;负数代表当前对象小
    	public int compareTo(Object o); 
    }
    --------------------------------------------------------------------------------
    package com.atguigu.exer3;
    /*
     * 定义一个ComparableCircle类,继承Circle类并且实现CompareObject接口。
     * 在ComparableCircle类中给出接口中方法compareTo的实现体,用来比较两个圆的半径大小。
     */
    public class ComparableCircle extends Circle implements CompareObject{
    	
    	public ComparableCircle(double radius) {
    		super(radius);
    	}
    	@Override
    	public int compareTo(Object o) {
    		if(this == o){
    			return 0;
    		}
    		if(o instanceof ComparableCircle){
    			ComparableCircle c = (ComparableCircle)o;
    			//错误的:
    //			return (int) (this.getRadius() - c.getRadius());
    			//正确的方式一:
    //			if(this.getRadius() > c.getRadius()){
    //				return 1;
    //			}else if(this.getRadius() < c.getRadius()){
    //				return -1;
    //			}else{
    //				return 0;
    //			}
    			//当属性radius声明为Double类型时,可以调用包装类的方法
    			//正确的方式二:
    			return this.getRadius().compareTo(c.getRadius());
    		}else{
    //			return 0;
    			throw new RuntimeException("传入的数据类型不匹配");
    		}	
    	}	
    }
    ------------------------------------------------------------------------------------------
    package com.atguigu.exer3;
    /*
     * 定义一个Circle类,声明radius属性,提供getter和setter方法
     */
    public class Circle {	
    	private Double radius;
    	public Double getRadius() {
    		return radius;
    	}
    	public void setRadius(Double radius) {
    		this.radius = radius;
    	}
    	public Circle() {
    		super();
    	}
    	public Circle(Double radius) {
    		super();
    		this.radius = radius;
    	}
    }
    ------------------------------------------------------------------------------------------
    package com.atguigu.exer3;
    public class ComparableCircleTest {
    	public static void main(String[] args) {
    		ComparableCircle c1 = new ComparableCircle(3.4);
    		ComparableCircle c2 = new ComparableCircle(3.6);
    		
    		int compareValue = c1.compareTo(c2);
    		if(compareValue > 0){
    			System.out.println("c1对象大");
    		}else if(compareValue < 0){
    			System.out.println("c2对象大");
    		}else{
    			System.out.println("c1与c2一样大");
    		}
    		int compareValue1 = c1.compareTo(new String("AA"));
    		System.out.println(compareValue1);
    	}
    }
    
    

    59.java8接口扩展:

    package com.atguigu.java8;
    
    /*
     * JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法
     */
    public interface CompareA {
    	//静态方法
    	public static void method1(){
    		System.out.println("CompareA:北京");
    	}
    	//默认方法
    	public default void method2(){
    		System.out.println("CompareA:上海");
    	}
    	default void method3(){
    		System.out.println("CompareA:上海");
    	}
    }
    ------------------------------------------------------------------------------------------
    package com.atguigu.java8;
    public interface CompareB {
    	default void method3(){
    		System.out.println("CompareB:上海");
    	}
    }
    ------------------------------------------------------------------------------------------
    package com.atguigu.java8;
    
    public class SubClassTest {
    	public static void main(String[] args) {
    		SubClass s = new SubClass();	
    //		s.method1();
    //		SubClass.method1();
    		//知识点1:接口中定义的静态方法,只能通过接口来调用。
    		CompareA.method1();
    		//知识点2:通过实现类的对象,可以调用接口中的默认方法。
    		//如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写以后的方法
    		s.method2();
    		//知识点3:如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的默认方法,
    		//那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法。-->类优先原则
    		//知识点4:如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,
    		//那么在实现类没有重写此方法的情况下,报错。-->接口冲突。
    		//这就需要我们必须在实现类中重写此方法
    		s.method3();	
    	}
    }
    class SubClass extends SuperClass implements CompareA,CompareB{
    	public void method2(){
    		System.out.println("SubClass:上海");
    	}
    	public void method3(){
    		System.out.println("SubClass:深圳");
    	}
    	//知识点5:如何在子类(或实现类)的方法中调用父类、接口中被重写的方法
    	public void myMethod(){
    		method3();//调用自己定义的重写的方法
    		super.method3();//调用的是父类中声明的
    		//调用接口中的默认方法
    		CompareA.super.method3();
    		CompareB.super.method3();
    	}
    }
    ---------------------------------------------------------------------------------------
    package com.atguigu.java8;
    public class SuperClass {	
    	public void method3(){
    		System.out.println("SuperClass:北京");
    	}	
    }
    

    60.java内部类:

    package com.atguigu.java2;
    /*
     * 类的内部成员之五:内部类
     * 1. Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类
     * 2.内部类的分类:成员内部类(静态、非静态)  vs 局部内部类(方法内、代码块内、构造器内)
     * 3.成员内部类:
     * 		一方面,作为外部类的成员:
     * 			>调用外部类的结构
     * 			>可以被static修饰
     * 			>可以被4种不同的权限修饰
     * 		另一方面,作为一个类:
     * 			> 类内可以定义属性、方法、构造器等
     * 			> 可以被final修饰,表示此类不能被继承。言外之意,不使用final,就可以被继承
     * 			> 可以被abstract修饰
     * 4.关注如下的3个问题
     *   4.1 如何实例化成员内部类的对象
     *   4.2 如何在成员内部类中区分调用外部类的结构
     *   4.3 开发中局部内部类的使用  见《InnerClassTest1.java》
     * 
     */
    public class InnerClassTest {
    	public static void main(String[] args) {
    		//创建Dog实例(静态的成员内部类):
    		Person.Dog dog = new Person.Dog();
    		dog.show();
    		//创建Bird实例(非静态的成员内部类):
    //		Person.Bird bird = new Person.Bird();//错误的
    		Person p = new Person();
    		Person.Bird bird = p.new Bird();
    		bird.sing();
    		System.out.println();
    		bird.display("黄鹂");
    	}
    }
    class Person{
    	String name = "小明";
    	int age;
    	public void eat(){
    		System.out.println("人:吃饭");
    	}
    	//静态成员内部类
    	static class Dog{
    		String name;
    		int age;
     
    		public void show(){
    			System.out.println("卡拉是条狗");
    //			eat();
    		}
    	}
    	//非静态成员内部类
    	class Bird{
    		String name = "杜鹃";
    		public Bird(){
    		}
    		public void sing(){
    			System.out.println("我是一只小小鸟");
    			Person.this.eat();//调用外部类的非静态属性
    			eat();
    			System.out.println(age);
    		}
     
    		public void display(String name){
    			System.out.println(name);//方法的形参
    			System.out.println(this.name);//内部类的属性
    			System.out.println(Person.this.name);//外部类的属性
    		}
    	}
    	public void method(){
    		//局部内部类
    		class AA{
    		}
    	}
    	{
    		//局部内部类
    		class BB{
    		}
    	}
    	public Person(){
    		//局部内部类
    		class CC{
    		}
    	}
    }
    ------------------------------------------------------------------------------------------
    package com.atguigu.java2;
    public class InnerClassTest1 {
    	//开发中很少见
    	public void method(){
    		//局部内部类
    		class AA{
    		}
    	}
    	//返回一个实现了Comparable接口的类的对象
    	public Comparable getComparable(){
    		//创建一个实现了Comparable接口的类:局部内部类
    		//方式一:
    //		class MyComparable implements Comparable{
    //
    //			@Override
    //			public int compareTo(Object o) {
    //				return 0;
    //			}		
    //		}
    //		return new MyComparable();
    		//方式二:
    		return new Comparable(){
    			@Override
    			public int compareTo(Object o) {
    				return 0;
    			}
    		};
    	}
    }
    -----------------------------------------内部类使用局部变量--------------------------------------
    package com.atguigu.java;
    public class InnerClassTest {
    //	public void onCreate(){
    //		int number = 10;
    //		View.OnClickListern listener = new View.OnClickListener(){	
    //			public void onClick(){
    //				System.out.println("hello!");
    //				System.out.println(number);
    //			}}	
    //		button.setOnClickListener(listener);	
    //	}
    	/*
    	 * 在局部内部类的方法中(比如:show)如果调用局部内部类所声明的方法(比如:method)中的局部变量(比如:num)的话,
    	 * 要求此局部变量声明为final的。
    	 * jdk 7及之前版本:要求此局部变量显式的声明为final的
    	 * jdk 8及之后的版本:可以省略final的声明
    	 * 
    	 */
    	public void method(){
    		//局部变量,是一个final的变量
    		int num = 10;
    		class AA{
    			public void show(){
    //				num = 20;
    				System.out.println(num);
    			}}}}
    

    61.java异常

    package com.atguigu.java;
    /*
     * Error:
     * Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。比如:StackOverflowError和OOM。
     * 一般不编写针对性的代码进行处理。
     */
    public class ErrorTest {
    	public static void main(String[] args) {
    		//1.栈溢出:java.lang.StackOverflowError
    //		main(args);
    		//2.堆溢出:java.lang.OutOfMemoryError 
    		Integer[] arr = new Integer[1024*1024*1024];
    	}
    }
    ------------------------------------------异常种类-------------------------------------------------
    package com.atguigu.java1;
    import java.io.File;
    import java.io.FileInputStream;
    import java.util.Date;
    import java.util.Scanner;
    import org.junit.Test;
    /*
     * 一、异常体系结构
     * 
     * java.lang.Throwable
     * 		|-----java.lang.Error:一般不编写针对性的代码进行处理。
     * 		|-----java.lang.Exception:可以进行异常的处理
     * 			|------编译时异常(checked)
     * 					|-----IOException
     * 						|-----FileNotFoundException
     * 					|-----ClassNotFoundException
     * 			|------运行时异常(unchecked,RuntimeException)
     * 					|-----NullPointerException
     * 					|-----ArrayIndexOutOfBoundsException
     * 					|-----ClassCastException
     * 					|-----NumberFormatException
     * 					|-----InputMismatchException
     * 					|-----ArithmeticException
     * 
     * 
     * 
     * 面试题:常见的异常都有哪些?举例说明
     */
    public class ExceptionTest {
    	//******************以下是编译时异常***************************
    	@Test
    	public void test7(){
    //		File file = new File("hello.txt");
    //		FileInputStream fis = new FileInputStream(file);
    //		
    //		int data = fis.read();
    //		while(data != -1){
    //			System.out.print((char)data);
    //			data = fis.read();
    //		}
    //		
    //		fis.close();
    	}
    	//******************以下是运行时异常***************************
    	//ArithmeticException
    	@Test
    	public void test6(){
    		int a = 10;
    		int b = 0;
    		System.out.println(a / b);
    	}
    	//InputMismatchException
    	@Test
    	public void test5(){
    		//输入不匹配
    		Scanner scanner = new Scanner(System.in);
    		int score = scanner.nextInt();
    		System.out.println(score);
    		scanner.close();
    	}
    	//NumberFormatException
    	@Test
    	public void test4(){
    		//格式异常
    		String str = "123";
    		str = "abc";
    		int num = Integer.parseInt(str);
    	}
    	//ClassCastException
    	@Test
    	public void test3(){
    		//类型转换异常
    		Object obj = new Date();
    		String str = (String)obj;
    	}
    	//IndexOutOfBoundsException
    	@Test
    	public void test2(){
    		//ArrayIndexOutOfBoundsException
    //		int[] arr = new int[10];
    //		System.out.println(arr[10]);
    		//StringIndexOutOfBoundsException
    		String str = "abc";
    		System.out.println(str.charAt(3));
    	}
    	//NullPointerException
    	@Test
    	public void test1(){
    //		int[] arr = null;
    //		System.out.println(arr[3]);
    		String str = "abc";
    		str = null;
    		System.out.println(str.charAt(0));
    	}
    }
    --------------------------------------------try-catch-finally----------------------------------------
    package com.atguigu.java1;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import org.junit.Test;
    /*
     * 一、异常的处理:抓抛模型
     * 过程一:"抛":程序在正常执行的过程中,一旦出现异常,就会在异常代码处生成一个对应异常类的对象。
     *           并将此对象抛出。
     *           一旦抛出对象以后,其后的代码就不再执行。
     * 		关于异常对象的产生:① 系统自动生成的异常对象
     * 					 ② 手动的生成一个异常对象,并抛出(throw)
     * 过程二:"抓":可以理解为异常的处理方式:① try-catch-finally  ② throws
     * 二、try-catch-finally的使用
     * try{
     * 		//可能出现异常的代码
     * }catch(异常类型1 变量名1){
     * 		//处理异常的方式1
     * }catch(异常类型2 变量名2){
     * 		//处理异常的方式2
     * }catch(异常类型3 变量名3){
     * 		//处理异常的方式3
     * }
     * ....
     * finally{
     * 		//一定会执行的代码
     * }
     * 说明:
     * 1. finally是可选的。
     * 2. 使用try将可能出现异常代码包装起来,在执行过程中,一旦出现异常,就会生成一个对应异常类的对象,根据此对象
     *    的类型,去catch中进行匹配
     * 3. 一旦try中的异常对象匹配到某一个catch时,就进入catch中进行异常的处理。一旦处理完成,就跳出当前的
     *    try-catch结构(在没有写finally的情况)。继续执行其后的代码
     * 4. catch中的异常类型如果没有子父类关系,则谁声明在上,谁声明在下无所谓。
     *    catch中的异常类型如果满足子父类关系,则要求子类一定声明在父类的上面。否则,报错
     * 5. 常用的异常对象处理的方式: ① String  getMessage()    ② printStackTrace()
     * 6. 在try结构中声明的变量,再出了try结构以后,就不能再被调用
     * 7. try-catch-finally结构可以嵌套
     * 体会1:使用try-catch-finally处理编译时异常,是得程序在编译时就不再报错,但是运行时仍可能报错。
     *     相当于我们使用try-catch-finally将一个编译时可能出现的异常,延迟到运行时出现。
     * 体会2:开发中,由于运行时异常比较常见,所以我们通常就不针对运行时异常编写try-catch-finally了。
     *      针对于编译时异常,我们说一定要考虑异常的处理。
     */
    public class ExceptionTest1 {
    	@Test
    	public void test2(){
    		try{
    			File file = new File("hello.txt");
    			FileInputStream fis = new FileInputStream(file);
    			int data = fis.read();
    			while(data != -1){
    				System.out.print((char)data);
    				data = fis.read();
    			}
    			fis.close();
    		}catch(FileNotFoundException e){
    			e.printStackTrace();
    		}catch(IOException e){
    			e.printStackTrace();
    		}
    	}
    	@Test
    	public void test1(){
    		String str = "123";
    		str = "abc";
    		int num = 0;
    		try{
    			num = Integer.parseInt(str);
    			System.out.println("hello-----1");
    		}catch(NumberFormatException e){
    //			System.out.println("出现数值转换异常了,不要着急....");
    			//String getMessage():
    //			System.out.println(e.getMessage());
    			//printStackTrace():
    			e.printStackTrace();
    		}catch(NullPointerException e){
    			System.out.println("出现空指针异常了,不要着急....");
    		}catch(Exception e){
    			System.out.println("出现异常了,不要着急....");
    		}
    		System.out.println(num);
    		System.out.println("hello-----2");
    	}
    }
    -------------------------------------------throws----------------------------------------------
    package com.atguigu.java1;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    /*
     * 异常处理的方式二:throws + 异常类型
     * 1. "throws + 异常类型"写在方法的声明处。指明此方法执行时,可能会抛出的异常类型。
     *     一旦当方法体执行时,出现异常,仍会在异常代码处生成一个异常类的对象,此对象满足throws后异常
     *     类型时,就会被抛出。异常代码后续的代码,就不再执行!
     * 2. 体会:try-catch-finally:真正的将异常给处理掉了。
     *        throws的方式只是将异常抛给了方法的调用者。  并没有真正将异常处理掉。  
     * 3. 开发中如何选择使用try-catch-finally 还是使用throws?
     *   3.1 如果父类中被重写的方法没有throws方式处理异常,则子类重写的方法也不能使用throws,意味着如果
     *       子类重写的方法中有异常,必须使用try-catch-finally方式处理。
     *   3.2 执行的方法a中,先后又调用了另外的几个方法,这几个方法是递进关系执行的。我们建议这几个方法使用throws
     *       的方式进行处理。而执行的方法a可以考虑使用try-catch-finally方式进行处理。
     */
    public class ExceptionTest2 {
    	public static void main(String[] args){
    		try{
    			method2();
    		}catch(IOException e){
    			e.printStackTrace();
    		}
    //		method3();
    	}
    	public static void method3(){
    		try {
    			method2();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    	public static void method2() throws IOException{
    		method1();
    	}
    	public static void method1() throws FileNotFoundException,IOException{
    		File file = new File("hello1.txt");
    		FileInputStream fis = new FileInputStream(file);
    		int data = fis.read();
    		while(data != -1){
    			System.out.print((char)data);
    			data = fis.read();
    		}
    		fis.close();
    		System.out.println("hahaha!");
    	}
    }
    

    62.java异常2:

    -----------------------------------------------自定义异常--------------------------------------------
    package com.atguigu.java2;
    /*
     * 如何自定义异常类?
     * 1. 继承于现有的异常结构:RuntimeException 、Exception
     * 2. 提供全局常量:serialVersionUID
     * 3. 提供重载的构造器
     * 
     */
    public class MyException extends Exception{
    	static final long serialVersionUID = -7034897193246939L;
    	public MyException(){	
    	}
    	public MyException(String msg){
    		super(msg);
    	}
    }
    --------------------------------------------练习-------------------------------------------------
    package com.atguigu.java2;
    public class StudentTest {
    	public static void main(String[] args) {
    		try {
    			Student s = new Student();
    			s.regist(-1001);
    			System.out.println(s);
    		} catch (Exception e) {
    //			e.printStackTrace();
    			System.out.println(e.getMessage());
    		}
    	}
    }
    class Student{
    	private int id;
    	public void regist(int id) throws Exception {
    		if(id > 0){
    			this.id = id;
    		}else{
    //			System.out.println("您输入的数据非法!");
    			//手动抛出异常对象
    //			throw new RuntimeException("您输入的数据非法!");
    //			throw new Exception("您输入的数据非法!");
    			throw new MyException("不能输入负数");
    			//错误的
    //			throw new String("不能输入负数");
    		}
    	}
    	@Override
    	public String toString() {
    		return "Student [id=" + id + "]";
    	}
    }
    -----------------------------------------练习2--------------------------------------------------
    package com.atguigu.exer;
    /*
     * 编写应用程序EcmDef.java,接收命令行的两个参数,要求不能输入负数,计算两数相除。
    	对数据类型不一致(NumberFormatException)、缺少命令行参数(ArrayIndexOutOfBoundsException、
      	除0(ArithmeticException)及输入负数(EcDef 自定义的异常)进行异常处理。
    提示: 
    	(1)在主类(EcmDef)中定义异常方法(ecm)完成两数相除功能。
    	(2)在main()方法中使用异常处理语句进行异常处理。
    	(3)在程序中,自定义对应输入负数的异常类(EcDef)。
    	(4)运行时接受参数 java EcmDef 20 10   //args[0]=“20” args[1]=“10”
    	(5)Interger类的static方法parseInt(String s)将s转换成对应的int值。
            如:int a=Interger.parseInt(“314”);	//a=314;
     */
    public class EcmDef {
    	public static void main(String[] args) {
    		try{
    			int i = Integer.parseInt(args[0]);
    			int j = Integer.parseInt(args[1]);
    			int result = ecm(i,j);
    			System.out.println(result);
    		}catch(NumberFormatException e){
    			System.out.println("数据类型不一致");
    		}catch(ArrayIndexOutOfBoundsException e){
    			System.out.println("缺少命令行参数");
    		}catch(ArithmeticException e){
    			System.out.println("除0");
    		}catch(EcDef e){
    			System.out.println(e.getMessage());
    		}
    	}
    	public static int ecm(int i,int j) throws EcDef{
    		if(i < 0 || j < 0){
    			throw new EcDef("分子或分母为负数了!");
    		}
    		return i / j;
    	}
    }
    -----------------------------------------------特殊情况----------------------------------------------
    package com.atguigu.java1;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import org.junit.Test;
    /*
     * try-catch-finally中finally的使用:
     * 1.finally是可选的
     * 2.finally中声明的是一定会被执行的代码。即使catch中又出现异常了,try中有return语句,catch中有
     * return语句等情况。
     * 3.像数据库连接、输入输出流、网络编程Socket等资源,JVM是不能自动的回收的,我们需要自己手动的进行资源的
     *   释放。此时的资源释放,就需要声明在finally中。
     */
    public class FinallyTest {
    	@Test
    	public void test2(){
    		FileInputStream fis = null;
    		try {
    			File file = new File("hello1.txt");
    			fis = new FileInputStream(file);
    			int data = fis.read();
    			while(data != -1){
    				System.out.print((char)data);
    				data = fis.read();
    			}
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}finally{
    			try {
    				if(fis != null)
    					fis.close();
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    	@Test
    	public void testMethod(){
    		int num = method();
    		System.out.println(num);
    	}
    	public int method(){
    		try{
    			int[] arr = new int[10];
    			System.out.println(arr[10]);
    			return 1;
    		}catch(ArrayIndexOutOfBoundsException e){
    			e.printStackTrace();
    			return 2;
    		}finally{
    			System.out.println("我一定会被执行");
    			return 3;
    		}
    	}
    	@Test
    	public void test1(){
    		try{
    			int a = 10;
    			int b = 0;
    			System.out.println(a / b);
    		}catch(ArithmeticException e){
    			e.printStackTrace();
    //			int[] arr = new int[10];
    //			System.out.println(arr[10]);
    		}catch(Exception e){
    			e.printStackTrace();
    		}
    //		System.out.println("我好帅啊!!!~~");
    		finally{
    			System.out.println("我好帅啊~~");
    		}
    	}
    }
    
  • 相关阅读:
    破解 inode 校园网多网卡限制方法
    更改 eclipse的 workplace路径
    VMware Network Adapter VMnet1和VMnet8 未识别的网络的解决方法
    eclipse更改xml文件,txt文件,property文件等文件编辑器的字体设置
    Lua中数组全排序
    Lua尾调用
    C++ 调用Lua简单例子
    linux生成core dump
    vc获取系统日期
    C++培训第一天
  • 原文地址:https://www.cnblogs.com/liuzhanghao/p/13521582.html
Copyright © 2020-2023  润新知