6.Java中的異常、斷言、日誌【草稿中】
如何開啓Java的斷言?
簡單說斷言就等於 對一個布爾表達式進行判別,如果爲真,那麼相安無事,如果爲假,那麼拋出異常
首先是第一個博客裏的第一段代碼
//代碼段A
public class AssertionDriver {
public static void main(String args[]){
Employee employee = new Employee();
employee.setName("Lang Yu");
employee.setEmail("[email protected]");
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("[email protected]");
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("[email protected]");
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裏有着三種開啓的方式。