JavaSE——访问控制权限、jar、单例和异常

1.包的定义及使用

包的本质实际上就属于一个文件夹,在项目开发中很难避免类名称重复的问题,如果所有的java文件都放在一个文件夹中,就有可能存在覆盖问题

1.1.包的导入

开发中使用包的定义之后,相当于把一个大的项目分别按照一定要求保存在了不同的包之中,但是这些程序类一定会发生互相调用的情况,这个时候就需要包的导入

类使用class和public class的区别:

  • public class: 文件名称必须与类名称保持一致,如果希望一个类被其他包访问,则必须定义为public class
  • class: 文件名称可以与类名称不一致,在一个*.java中可以定义多个class,但是这个类不允许被其他包所访问

需要注意的是,导入的语句为"import 包.类"这样只会导入一个类,如果说现在导入一个包中的多个类,可以直接采用通配符"*“来完成,这种”*"并不意味要将包中的所有类都进行导入,而是根据你的需求来导入

不同包但是相同类名的情况,这个时候如果还是直接使用类就会产生一个编译上的歧义,这个时候我们一般在使用时使用全名称定义

1.2.系统常用包

  • java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入
  • java.lang.reflect:java 反射编程包
  • java.net:进行网络编程开发包
  • java.sql:进行数据库开发的支持包
  • java.util:是java提供的工具程序包(集合类等)
  • java.io:IO编程开发包
  • java.awt(离不开windows平台)、java.swing:UI开发包,主要进行界面开发包,目前已经不用了

1.3.访问控制权限

在java 中提供有四种访问控制权限:
private<default<protected<public,这四种访问控制权限的定义如下:
在这里插入图片描述
对于public永远都可以访问,对于封装性而言主要是private、default、protected权限,在不同包中,只有子类能访问父类中的protected权限

关于权限选择:

  • 对于封装的描述90%使用private,只有10%会使用protected,这两个都叫封装
  • 属性都使用private,方法都使用public

2.jar命令

jar本质上也是一种压缩文件,里面保存的都是*.class文件。也就是说现在要实现某一个功能模块,可能有几百个类,最终交付给用户使用时,为了方便管理,就会将这些文件形成压缩包提供给用户。在JDK中提供实现jar文件操作的命令,只需要输入一个jar即可。对于此命令,有如下几个常用参数:

  • “c”:创建新档案
  • “f”:指定档案文件名
  • “v”:在标准输出中生成详细输出

编译源文件并打包:

public class Message {
	public void print() {
		System.out.println("Hello I am Message");
	}
}

对上述源文件编译而后变为jar文件:

  • 打包进行程序编译:javac -d . Message.java
  • 将生成的程序类打包为jar文件:jar -cvf Message.jar Message.class

打开后发现有一个META-INF文件夹,里面包含版本号等信息,此时的Message.jar就包含我们需要的程序类

要想使用jar文件,并不是说将其放到程序的目录之中就可以,还需要配置CLASSPATH,设置jar文件的加载路径才会起效,开发中会使用大量的jar文件,所有的jar文件必须配置在classpath中

3.单例设计模式&多例设计模式

3.1.单例设计模式

所谓的单例设计:

  • 一个类只允许产生一个实例化对象
  • 此实例化对象由自己产生
  • 仅提供给其他对象这唯一实例

3.2.饿汉式单例(上来就new)

class Singleton{
	//在类的内部可以访问私有结构,所以可以在类的内部产生实例化对象
	private final static Singleton INSTANCE = new Singleton() ;

	//私有化构造
	private Singleton() {
	}
	
	//静态方法返回一个对象
	public static Singleton getInstance() {
		return INSTANCE ;
	}
}

饿汉式单例:

  • 线程安全
  • 耗费资源
  • 适用于单例对象占用资源少

3.3.懒汉式单例(用时再new)

class Singleton{
	private static Singleton instance ;
	
	//私有化构造
	private Singleton() { 
	}
	
	//静态方法返回一个对象
	public static Singleton getInstance() {
		if (instance==null) { 
			// 表示此时还没有实例化
			instance = new Singleton() ;
		}
		return instance ;
	}
}

懒汉式单例:

  • 第一次调用时才初始化。在并发情况下可能new出多个实例
  • 线程不安全
  • 但是不耗费资源

3.4.懒汉式单例的优化(双重检查)

public class Singleton{
	//私有该实例和构造方法
	private static volatile Singleton instance;
	private Singleton(){}
	//双重检查
	public static Singleton getInstance(){
		//检查此时是否new了
		if(null == instance){
			//锁住类对象,保证只有一个对象进入代码块
			synchronized(Singleton.class){
				//确保是第一次new操作
				if(null == instance){
					instance = new Singleton();
				}
			}
		}
		return instance;
	}
}

volatile在此的作用:禁止指令重排,因为new一个对象会有三部操作:

  • 堆上分配空间
  • 属性初始化
  • 引用指向对象

此处使用volatile防止指令重排new出残疾实例


实际上单例最靠谱的方式是通过枚举,因为枚举单个元素本身就是单例,这样可以有效防止通过反射、反序列化等手段破坏单例,由JVM从根本上保证,至于多例模式,该概念已经被枚举代替

4.异常体系

4.1.受查异常与非受查异常

先来看一下异常的继承类结构:
在这里插入图片描述

  • Error:描述Java运行时内部错误与资源耗尽错误。这种内部错误一旦出现,除了告知用户并使程序安全终止以外,再无能为力。
  • Exception(程序出错):
  • IOException:程序本身没问题,由于IO处理导致的程序错误
  • RuntimeException:由于程序错误导致的
  • 非受查异常(无需强制处理):继承于Error或RuntimeException(空指针异常,类型转换异常,数组越界异常)的异常类称为非受查异常
  • 受查异常(必须强制处理):直接继承于Exception与IOException的称为受查异常

4.2.异常处理格式

try{
	有可能出现异常的语句 ;
}[catch (异常类 对象) {

} ... ]
[finally {
	异常的出口
}]

对于以上三个关键字,可以出现的组合:try…catch、try…finally、try…catch…finally,出现了异常之后,由于存在异常处理机制,依然可以正常执行完毕,还可以调用所有异常类中提供的printStackTrace()方法进行完整异常信息的输出,注意:有finally块时,无论try catch中是否有返回语句,最终都会执行finally块

4.3.throws关键字(作用在方法上)

在进行方法定义的时候,如果要告诉调用者本方法可能产生哪些异常,就可以使用throws方法进行声明,如果该方法出现问题后不希望进行处理,就使用throws抛出,如果现在调用了throws声明的方法,那么在调用时必须明确的使用try…catch…进行捕获,因为该方法有可能产生异常,所以必须按照异常的方式来进行处理,主方法本身也属于一个方法,所以主方法上也可以使用throws进行异常抛出,这个时候如果产生了异常就会交给JVM处理

4.4.throw关键字(作用在方法内)

thorw是直接编写在语句之中,表示人为进行异常的抛出,如果现在异常类对象不希望由JVM产生而由用户产生实例,就可以使用throw来完成


解释throw和throws的区别:

  • throw用于方法内部,主要表示手工异常抛出
  • throws主要在方法声明上使用,明确告诉用户本方法可能产生的异常,同时该方法可能不处理此异常

4.5.RuntimeException类

很多的代码上都可能出现异常,例如"10/0"都可能产生异常,如果所有可能产生异常的地方都强制性异常处理,这个代码就太复杂了。所以在异常设计的时候,考虑到一些异常可能是简单问题, 所以将这类异常称为RuntimeException,也就是使用RuntimeException定义的异常类可以不需要强制性进行异常处理


请解释Exception与RuntimeException的区别,请列举几个常见的RuntimeException:

  • Exception是RuntimeException的父类,使用Exception定义的异常都要求必须使用异常处理,而使用RuntimeException定义的异常可以由用户选择性的来进行异常处理
  • 常见的RuntimeException:ClassCastException、NullPointerException等

5.断言

  • 启动断言需要使用-ea参数传给虚拟机,手工开启,默认不开启断言
  • AssertionError:断言异常(错误)->非受查异常
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值