6.Java中的异常、断言、日志【草稿中】
如何开启Java的断言?
简单说断言就等于 对一个布尔表达式进行判别,如果为真,那么相安无事,如果为假,那么抛出异常
首先是第一个博客里的第一段代码
//代码段A
public class AssertionDriver {
public static void main(String args[]){
Employee employee = new Employee();
employee.setName("Lang Yu");
employee.setEmail("silentbalanceyh@126.com");
businessProcess(employee);
}
public static void businessProcess(Employee employee){
try{
assert employee.getName() != null &&
employee.getEmail() != null &&
employee.getPassword() != null:
employee;
}catch(AssertionError error){
System.out.println(error);
}
}
}
class Employee{
private String name;
private String email;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString(){
return "/nName:" + name + "/n" + "Email:" + email + "/n" + "Password:" + password;
}
}
/*下面是代码出处
————————————————
版权声明:本文为CSDN博主「戒子猪」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/silentbalanceyh/article/details/4564884
*/
为什么呢第一段代码不好使呢?
首先我们需要知道的是java里默认是关闭了断言的功能的,如果我们想用断言,就得手动开启,那么如何开启呢?
package others;
class Loaded
{
public void go()
{
try
{
assert false:"Loaded.go()";
}
catch(AssertionError error){
System.out.println(error);
}
}
}
public class LoaderAssertions
{
public static void main(String[] args)
{
ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
new Loaded().go();
}
}
上面的代码是可以抛出断言异常的,但当我们把ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
注释掉,这个代码就不会抛出断言异常。另一种方式是,我们可以把上面那段代码注释掉,但需要配置运行参数,如下所示
Run —> Run Configurations —> 选择 Arguments 选项卡
在 VM arguments 文本框中输入“-ea” 如果输入 -da 表示禁止断言
如果我们对运行参数进行了配置,第一段代码是能够抛出异常的。
那如果我不想配置运行参数,我希望在代码里手动开启呢?理所应当地在代码里添加了ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
,如下面代码所示
//代码段B
public class AssertionDriver {
public static void main(String args[]){
ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
Employee employee = new Employee();
employee.setName("Lang Yu");
employee.setEmail("silentbalanceyh@126.com");
businessProcess(employee);
}
public static void businessProcess(Employee employee){
try{
assert employee.getName() != null &&
employee.getEmail() != null &&
employee.getPassword() != null:
employee;
}catch(AssertionError error){
System.out.println(error);
}
}
}
class Employee{
private String name;
private String email;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString(){
return "/nName:" + name + "/n" + "Email:" + email + "/n" + "Password:" + password;
}
}
我发现上述代码并不能按我们所想抛出断言异常,于是我进行了各种尝试修改,改成下面那样就可以了
//代码段C
package others;
public class AssertionDriver {
public static void main(String[] args) {
// ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
ClassLoader.getSystemClassLoader().setClassAssertionStatus("others.Employee",true);
// AssertionDriver.class.getClassLoader().setDefaultAssertionStatus(true);
// 上面是设置断言开启的三种方式
System.out.println(AssertionDriver.class.getClassLoader());
System.out.println(Employee.class.getClassLoader());
System.out.println(ClassLoader.getSystemClassLoader());
// 上述三个类加载器相同
Employee employee = new Employee();
employee.setName("Lang Yu");
employee.setEmail("silentbalanceyh@126.com");
employee.businessProcess();
}
}
class Employee {
public void businessProcess() {
try {
boolean check = this.getName() != null &&
this.getEmail() != null &&
this.getPassword() != null;
assert check : this.toString();
} catch (AssertionError error) {
System.out.println(error);
}
}
private String name;
private String email;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "\nName:" + name + "\n" + "Email:" + email + "\n" + "Password:" + password;
}
}
为什么呢?
第一篇博客里也说到了,我们可以允许某一部分的类和包开启断言功能,其他的类不允许(即使在这些不允许的类里使用了Assert
,这些语句会被跳过),但前提是,得在这个类被加载之前进行设置,因为如果类都加载完成了,那再设置就不管用了啊。同时我们要知道,类加载的时机是第一次遇到这类的时候(包括第一次调用静态方法、第一次调用构建方法等)
代码段B中,Assert
语句被用于AssertionDriver
类中,而这个类是程序的入口类,即运行主程序之前,这个类就已经被加载完毕了,我们再去打开断言开关,已经影响不了AssertionDriver
类了,而又是因为默认是关闭的,所以用不了了。
而代码段C中,Assert
语句被用于Employee
类,当执行到打开断言语句的时候,这个类还没有被加载进来,所以可以成功为Employee
类打开断言。代码段C里有着三种开启的方式。