內部類:
將一個類定義在另一個類的裏面,對裏面那個類就稱爲內部類(內置類,嵌套類)。
當描述事物時,事物的內部還有事物,該事物用內部類來描述。因爲內部事務在使用外部事物的內容。
訪問特點:
l 內部類可以直接訪問外部類中的成員,包括私有成員。
l 外部類要訪問內部類中的成員必須要建立內部類的對象。
l 局部內部類不能被private和static所修飾,因爲它們只能修飾成員。
l 局部內部類可以直接訪問外部類中的成員,因爲還持有外部類中的引用。但是不可以訪問它所在的局部中的變量,只能訪問被final修飾的局部變量。
class Outer
{
int x=3;
void method()
{
final int y=4;
class Inner//此爲局部內部類。
{
void funnction()
{
System.out.println(x);
System.out.println(y);//局部內部類要使用局部變量,此變量必須是final修飾的。原因是:因爲這個內部類存在於方法內方法內的局部變量雖說作用域是方法體內,但是它所包含的內部類卻不是與方法共存亡的,所以當方法執行完畢,方法的內存被釋放,而這個內部累還在使用該方法的一個不存在的局部變量是不合常理的,所以,被final修飾後值是不可變的,所以即便方法不存在了,那個值還是可以拿來繼續使用。也可以換個理解方式,那就是我們不是爲了給內部類使用才把局部變量用final修飾,而是被final修飾的,纔有資格被內部類使用。
}
}
new Inner().funnction();
}
}
l 當內部類在成員位置上,就可以被成員修飾符所修飾。
比如:private:將內部類在外部類中進行封裝。
Static:內部類就具備static的特性。只能直接訪問外部類中的static成員,出現了訪問侷限。
在外部其他類中,直接訪問static內部類的非靜態成員:
new outer.Inner().function();
在外部其他類中,直接訪問static內部類的靜態成員:
Outer.inner.function();
當內部類定義了靜態成員,該內部類必須是static。
當外部類中的靜態方法訪問內部類時,內部類也必須是static的。
新建內部類對象:
Outer.inner In = new Outer () .new Inner();
在有局部變量的時候變量的作用範圍:
之所以可以直接訪問外部類中的成員,是因爲內部類中持有一個外部類的引用,格式爲 外部類名.this 。
匿名內部類:
l 匿名內部類其實就是內部類的簡寫格式。
l 定義匿名內部類的前提是:內部類必須是繼承一個類或者實現接口。
l 匿名內部類格式: new 父類或者接口(){定義子類的內容}
l 其實匿名內部類就是一個匿名子類對象。而求這個對象有點“胖”可以理解爲帶內容的對象。
l 匿名內部類中定義的方法最好不超過3個。
public class AnonymityInnerClass {
public static void main(String[] args) {
Test.function().method();//此處調用了Inner接口的method方法,所以function方法返回了一個Inner的子類對象。
}
}
interface Inner
{
void method();
}
class Test
{
static Inner function()//通過匿名內部類實現。補足代碼。
{
return new Inner()//匿名內部類。
{
public void method()
{
System.out.println("method run");
}
};
}
}
--------------------------------------------------------------------------------
異常:就是程序運行時出現的不正常情況。
異常的好處:
1. 將問題進行封裝。
2. 將正常流程代碼和問題處理代碼相分離,方便於閱讀。
異常體系:
l Throwable
Error
通常出現重大問題如:運行的類不存在或者內存溢出等。
不編寫針對代碼對其處理
Exception
在運行時運行出現的一些情況,可以通過try catch finally處理
Exception和Error的子類名都是以父類名作爲後綴。
Exception和Error都具有一些共性內容。比如:不正常信息,引發原因等。
異常由來:
問題也是現實生活中一個具體的事物,也可以通過java的類的形式進行描述,並封裝成對象。其實就是java對不正常情況進行描述後的對象體現。
異常的處理:
Java提供了特有語句進行處理:
Try
{
需要被檢測的代碼
}
Catch (異常類 變量)
{
處理異常代碼:(處理方式)
(建立catch處理時,catch中一定要定義具體的處理方式。不要簡單定義一句e.printStacktrace(),也不要簡單的就書寫一條輸出語句。)
(異常的常見處理信息:
getMessage:得到異常信息;
toString:異常名稱:異常信息
printStackTrace:異常名稱,異常信息,異常出現的位置。
其實JVM默認的異常處理機制,就是在調用此方法,打 印異常的堆棧的跟蹤信息)
}
Finally
{
一定會執行的語句。
這條語句與方法中的語句的區別是:如果在處理中出現異常並且終止程序,那麼over不再執行,但是finally是始終執行。
Finally中定義的通常是關閉資源代碼。因爲資源必須釋放。
Finally只有一種情況不會執行。當執行到System。Exit(0);finally不會執行。
}
三種結合格式:
Try、catch try、finally try、catch、finally
對多異常的處理:
聲明異常時,建議聲明更爲具體的異常。這樣處理的可以更具體。
對方聲明幾個異常,就對應有幾個catch塊。不要定義多餘的catch塊。如果多個catch塊中的異常出現繼承關係,父類異常catch塊放到最下面。
public class ExceptionDemo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Demo d=new Demo();
try
{
int x=d.div(4, 0);
System.out.println(x);
}
catch(ArithmeticException e)
{
System.out.println(e.toString());
System.out.println("被零除了!");
}
catch(ArrayIndexOutOfBoundsException e)
{
System.out.println(e.toString());
System.out.println("角標越界了!");
}
}
}
class Demo
{
int div(int a,int b)throws ArithmeticException,ArrayIndexOutOfBoundsException
{
int[] arr=new int[4];
System.out.println(arr[3]);
return a/b;
}
}
自定義異常:
定義類繼承Exception或者RuntimeException
1. 爲了讓該自定義類具備可拋性。
2. 讓該類具備操作異常的共性方法。
當要定義自定義異常的信息時,可以使用父類已經定義好的功能。異常信息傳遞給父類的構造函數。
class MyException extends Exception
{
MyException(String mes)
{
Super(mes);
}
}
因爲項目中會出現特有的問題,而這些問題並未被java所描述並封裝對象。所以對於這些特有的問題可以按照java的對問題封裝思想,將特有的問題。進行自定義的異常封裝。
在一般情況下,函數內出現異常,函數上需要聲明。
當在函數內部出現了throw拋出異常對象,那麼就必須要給對應的處理動作。要麼在內部try catch處理。要麼在函數上聲明讓調用者處理。
如何定義異常信息呢?
必須是自定義類繼承Exception。因爲父類中已經把異常信息的操作都完成了。所以子類只要在構造時,將異常信息通過super語句傳遞給父類。那麼就可以直接通過getMessage方法獲取自定義的異常信息。
繼承exception原因是:異常體系有個特點:因爲異常類和異常對象都被拋出。他們都具備可拋型。這個可拋性是Throwable這個體系中獨有的特點。只有這個體系中的類和對象纔可以被throw和throws操作。
Throw和throws的區別:
Throws用在函數上, throw用在函數內。
Throws後面跟的異常類。可以跟多個,用逗號隔開。
Throw後跟的是異常對象。
對於異常分爲兩種:
編譯時被檢測的異常。
該異常在編譯時,如果沒有處理(沒有拋出也沒有try),編譯失敗。
該異常被標識,代表這可以被處理。
編譯時不被檢測的異常。(運行是異常。RuntimeException以及其子類)
在編譯時,不需要處理,編譯器不檢查。
該異常的發生,建議不處理,讓程序停止,需要對代碼進行修正。
Exception中有一個特殊的子類異常RuntimeException運行是異常。
如果在函數內容拋出該異常類,函數上可以不用聲明,編譯一樣通過。
如果在函數上聲明瞭該異常,調用者可以不用進行處理,編譯一樣通過。
之所以不用在函數聲明,是因爲不需要讓調用者處理。當該異常發生,希望程序停止,因爲在運行時,出現了無法繼續運算的情況,希望停止程序後對代碼進行修正。
所以說,自定義異常時:如果該異常的發生,無法在繼續運算時進行運算,就讓自定義異常繼承RuntimeException。
class Demo
{
int div(int a,int b)throws ArithmeticException,ArrayIndexOutOfBoundsException,FushuException//throws用在函數上,後面跟的是異常類。
{
if (b<0) {
throw new FushuException("出現了負數的情況",b);//throw用在函數內,後面跟的是異常對象
}
int[] arr=new int[4];
System.out.println(arr[3]);
return a/b;
}
}
class FushuException extends Exception
{
private String msg;
private int value;
FushuException(String msg,int value)
{
this.msg=msg;
this.value=value;
}
public String getMessage()
{
return msg;
}
public int getValue()
{
return value;
}
}
異常在子父類覆蓋中的體現:
1. 子類在覆蓋父類時,如果父類的方法拋出異常,那麼子類的覆蓋方法,只能拋出父類的異常或者該異常的子類。
2. 如果父類方法拋出多個異常,那麼子類在覆蓋方法時,只能拋出父類異常的子類。
3. 如果父類或者接口的方法中沒有異常拋出,那麼子類在覆蓋方法時,也可以拋出異常。如果子類方法發生了異常。就必須要進行try處理,絕對不能拋出。
異常的練習:
public class ComputerDemo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Teacher tea=new Teacher("畢老師");
try {
tea.prelect();
} catch (NoplanException e) {
// TODO Auto-generated catch block
System.out.println("換老師或放假");
}
}
}
class BluescreenException extends Exception
{
private static final long serialVersionUID = 1L;
BluescreenException(String message)
{
super(message);
}
}
class SmokeingException extends Exception
{
private static final long serialVersionUID = 1L;
SmokeingException(String message)
{
super(message);
}
}
class NoplanException extends RuntimeException
{
private static final long serialVersionUID = 1L;
NoplanException(String message)
{
super(message);
}
}
class Computer
{
private int state=2;
public void run()throws BluescreenException,SmokeingException
{
if(state==2)
throw new BluescreenException("藍屏了");
if(state==3)
throw new SmokeingException("冒煙了");
System.out.println("電腦運行");
}
public void reset()
{
state=1;
System.out.println("電腦重啓");
}
}
class Teacher
{
private String name;
private Computer cm;
Teacher(String name)
{
this.name=name;
cm=new Computer();
}
public void prelect()
{
try
{
cm.run();
}
catch (BluescreenException e)
{
System.out.println(e.toString());
cm.reset();
}
catch(SmokeingException e)//冒煙異常,teacher無法處理。拋出。
{
System.out.println(e.toString());
test();
throw new NoplanException("課時無法繼續");//不能處理的異常拋出。
//test();//寫到RuntimeException後面的語句無法執行到,會包異常。
}
System.out.println(name+"講課");
}
public void test()
{
System.out.println("練習");
}
}