Java基础巩固(自定义异常类、运行时异常与编译时异常、finally块、包、权限修饰符、jar包、模板模式 、清除数组中的重复元素)

一、自定义异常类

   sun提供了很多的异常类给我们用于描述程序中各种的不正常情况,但是sun 给我
提供异常类还不足以描述我们现实生活中所有不正常情况,那么这时候我们就需要

自定义异常类。

自定义异常类的步骤:  自定义一个类继承Exception即可。

//自定义了一个没有网线的异常类了。
class NoIpException extends Exception{


	public NoIpException(String message){
		super(message);  //调用了Exception一个参数的构造函数。
	}

}



class Demo2 
{
	public static void main(String[] args) 
	{
		String ip = "192.168.10.100";
		ip = null;
		try{
			feiQ(ip);  // 如果调用了一个声明抛出异常类型的方法,那么调用者必须要处理。
		
		
		}catch(NoIpException e){
			e.printStackTrace();
			System.out.println("马上插上网线!");
		}
		

	}


	public static void feiQ(String ip) throws NoIpException{
		if(ip==null){
			throw new  NoIpException("没有插网线啊,小白!");
		}
		System.out.println("正常显示好友列表..");
	}


}

二、运行时异常与编译时异常

异常体系:

--------| Throwable  所有错误或者异常的父类
--------------| Error(错误)
--------------| Exception(异常) 异常一般都通过代码处理

------------------| 运行时异常: 如果一个方法内部抛出了一个运行时异常,那么方法上 可以声明也可以不 声明,调用者可以以处理也可以不处理。
------------------| 编译时异常(非运行时异常、受检异常):  如果一个方法内部抛出了一个编译时异常对象,那么方法上就必须要声明,而且调用者也必须要处理。

运行时异常: RuntimeException以及RuntimeException子类 都是属于运行时异常。

编译时异常: 除了运行时异常就是编译异常。


疑问: 为什么java编译器会如此严格要求编译时异常,对运行时异常如此宽松?

    运行时异常都是可以通过程序员良好的编程习惯去避免,所以java编译器就没有严格要求处理运行时异常。


三、finally块

finally块的 使用前提是必须要存在try块才能使用。

finally块的代码在任何情况下都会执行的,除了jvm退出的情况。

finally非常适合做资源释放的工作,这样子可以保证资源文件在任何情况下都 会被释放。



try块的三种组合方式:


第一种: 比较适用于有异常要处理,但是没有资源要释放的。
         try{

            可能发生异常的代码
    
            }catch(捕获的异常类型 变量名){
                处理异常的代码
            }

第二种:比较适用于既有异常要处理又要释放资源的代码。
        
        try{

            可能发生异常的代码
    
            }catch(捕获的异常类型 变量名){
                处理异常的代码
            }finally{
                释放资源的代码;
            }

第三种: 比较适用于内部抛出的是运行时异常,并且有资源要被释放。
           try{

            可能发生异常的代码
    
            }finally{
                释放资源的代码;
            }
    

class Demo5 
{
	public static void main(String[] args) 
	{
		//System.out.println("Hello World!");
		div(4,0);
	}


	public static void div(int a, int b){
		try{
			if(b==0){
				System.exit(0);//退出jvm
			}
			int c = a/b;
			System.out.println("c="+ c);

		}catch(Exception e){
			System.out.println("出了除数为0的异常...");
			throw e;
		}finally{
			System.out.println("finall块的代码执行了..");
		}
	}
}
//fianlly释放资源的代码
import java.io.*;
class Demo6 
{
	public static void main(String[] args) 
	{
		FileReader fileReader = null;
		try{
			//找到目标文件
			File file = new File("f:\\a.txt");
			//建立程序与文件的数据通道
			fileReader = new FileReader(file);
			//读取文件
			char[] buf = new char[1024];
			int length = 0; 
			length = fileReader.read(buf);
			System.out.println("读取到的内容:"+ new String(buf,0,length));
		}catch(IOException e){
			System.out.println("读取资源文件失败....");
		}finally{
			try{
				//关闭资源
				fileReader.close();
				System.out.println("释放资源文件成功....");
			}catch(IOException e){
				System.out.println("释放资源文件失败....");
			}
		}

	}
}

四、包

java中的包就相当于windows文件夹。

包的作用:
    1. 解决类名重复产生冲突的问题。
    2. 便于软件版本的发布。


定义包的格式:
    package 包名;

包名命名规范:包名全部小写。

包语句要注意的事项:
    1. package语句必须位于java文件中中第一个语句。
    2. 如果一个类加上了包语句,那么该类的完整类名就是: 包名.类名
    3. 一个java文件只能有一个包语句。


问题:  每次编译的时候都需要自己创建一个文件夹,把对应 的class文件存储 到文件夹中。
    
        javac -d 指定类文件的存放路径   java源文件

有了包之后类与类之间的访问:

问题: 有了包之后类与类之间的访问每次都必须 要写上包名!烦!!!!

解决方案: sum提供导包语句让我们解决该问题。

导包语句作用:简化书写。 (误区: 把一个类导入到内存中)

导包语句的格式:
             import 包名.类名;   (导入xxx包中某个类)

导包语句要注意的细节:
     1. 一个java文件中可以出现多句导包语句。
     2. "*"是 导包语句的通配符。可以匹配任何 的类名。
     3. import aa.*; 是不会作用于aa包下面的子包的。
    
推荐使用:import 包名.类名;   因为使用*通配符会导致结构不清晰。

什么时候使用import语句:
    1. 相互访问的两个类不是在同一个包下面,这时候就需要使用到导包语句。

    2. java.lang 是默认导入 的,不需要我们自己导入。

五、权限修饰符

            权限修饰符就是控制被修饰的成员的范围可见性。


            public(公共)        protected(受保护)           default(缺省)       private (大到小)

同一个类      true                 true                        true                 true


同一个包      true                 true                        true                  false

 
子父类        true                  true                      false                   false


不同包        true                 false                      false                   false


六、打jar包

需要使用到jdk的开发工具(jar.exe).

    
jar的用法:
    
使用格式:
 
    jar cvf jar文件的名字  class文件或者是文件夹

打jar包要注意的事项:
    1. 一个程序打完了jar之后 必须要在清单文件上指定入口类: 格式 Main-Class: 包名.类名
    2. jar包双击运行仅对于图形化界面的程序起作用,对控制台的程序不起作用。


jar文件的作用:
    1. 方便用户快速运行一个项目。
    2. 提供工具类以jar包的形式给别人使用。


如果使用jar包里面的类必须要先设置classpath路径。

jre = jvm+ 核心类库


注意: 在不同包下面只有public 与 protected 可以访问,而且protected必须是在继承关系下才能够访问。


七、模板模式

  解决某类事情的步骤有些是固定的,有些是会发生变化的,那么这时候我们可以

为这类事情提供一个模板代码,从而提高效率 。


需求;编写一个计算程序运行时间 的模板。

模板模式的步骤:
    1. 先写出解决该类事情其中 的一件的解决方案。
    2. 分析代码,把会发生变化的代码抽取出来独立成一个方法。把该方法描述成一个抽象的方法。
    3. 使用final修饰模板方法,防止别人 重写你的模板方法。


八、清除数组中的重复元素

目前有数组” int[] arr =  {11,2, 4, 2, 10, 11},
定义一个函数清除该数组的重复元素,返回的数组存储了那些非重复的元素而且数组不准浪费长度。

分析:
    1. 确定新数组的长度。  原数组的长度-重复元素个数


import java.util.*;
class Demo12 {

	public static void main(String[] args) 
	{
		int[] arr =  {11,2, 4, 2, 10, 11};
		arr = clearRepeat(arr);
		System.out.println("清除重复元素的数组:"+ Arrays.toString(arr));
	}

	public static int[] clearRepeat(int[] arr){
		//先计算出重复元素的格式:
		int count = 0; //记录重复元素的个数
		for(int i = 0 ; i < arr.length-1 ; i++){
			for(int j = i+1 ; j<arr.length ; j++){
				if(arr[i]==arr[j]){
					count++;
					break;
				}
			}
		}
		
		//新数组 的长度
		int newLength = arr.length - count;
		//创建一个新的数组
		int[] newArr = new int[newLength];

		int index = 0 ; 	//新数组的索引值

		
		//遍历旧数组
		for(int i = 0  ; i< arr.length ; i++){
			int temp = arr[i];  //旧数组中的元素 
			boolean flag = false;  //默认不是重复元素
			
			
			//拿着旧数组 的元素 与新数组的每个元素比较一次。
			for(int j = 0 ; j< newArr.length ; j++){
				if(temp==newArr[j]){
					flag = true;
					break;
				}
			}
			
			if(flag == false){
				newArr[index++] = temp;
			}
		}
		
		return newArr;
	}
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值