實驗4 包,接口與異常處理(exception)_第1頁
實驗4 包,接口與異常處理(exception)_第2頁
實驗4 包,接口與異常處理(exception)_第3頁
實驗4 包,接口與異常處理(exception)_第4頁
實驗4 包,接口與異常處理(exception)_第5頁
已閱讀5頁,還剩12頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、實驗4 包、接口與異常處理(exception)一、實驗目的了解Java 中包(package)、接口(interface)和異常處理(exception)的作用,掌握包、接口、異常處理的設計方法。二、實驗要求1. 了解Java 系統(tǒng)包的結構。2. 掌握創(chuàng)建自定義包的方法。3. 掌握使用系統(tǒng)接口的技術和創(chuàng)建自定義接口的方法。4. 理解系統(tǒng)異常處理的機制和創(chuàng)建自定義異常的方法。三、實驗內容(一) 了解并使用Java 的系統(tǒng)包1 API 包、接口、異常處理的作用包是類和接口的集合。利用包可以把常用的類或功能相似的類放在一個包中。Java 語言提供系統(tǒng)包,其中包含了大量的類,可以在編寫Java 程序

2、時直接引用它們。為便于管理和使用它們,將這些類分為了不同的包。包又稱類庫或API 包,所謂API(Application Program Interface)即應用程序接口。API 包方面提供豐富的類與方法供大家使用,如畫圖形、播放聲音等,另一方面又負責和系統(tǒng)軟硬件打交道,圓滿實現(xiàn)用戶程序的功能。所有Java API 包都以“java.”開頭,以區(qū)別用戶創(chuàng)建的包。接口解決了Java 不支持多重繼承的問題,可以通過實現(xiàn)多個接口達到與多重繼承相同的功能。處理程序運行時的錯誤和設計程序同樣重要,只有能夠完善處理運行時出錯的程序,軟件系統(tǒng)才能長期穩(wěn)定地運行,異常處理就是說明如何處理程序運行時出錯的問題

3、。2上網瀏覽Java API 文檔在地址 上,可以看到Java 系統(tǒng)提供的Java API 文檔,類文檔的內容主要是:類層次、類及用途描述、成員變量列表、構造方法列表、成員方法列表、從類層次上繼承的方法列表、成員變量的詳細說明、構造方法詳細說明、成員方法詳細說明。在這里可以看到Java 提供的Java API 文檔的最新內容。如圖4.1 所示。圖4.1在右上方選擇Class 標題,并在左下角框中移動滑塊,選擇object 類,可以看到object 類的所有方法和構造方法。如圖4.2 所示。圖4.23了解Applet 類的方法。(二) 創(chuàng)建并使用自定義包1自定義包的聲明方式<package

4、> <自定義包名>聲明包語句必須添加在源程序的第一行,表示該程序文件聲明的全部類都屬于這個包。2創(chuàng)建自定義包Mypackage在存放源程序的文件夾中建立一個子文件夾Mypackage。例如,在“E:java程序”文件夾之中創(chuàng)建一個與包同名的子文件夾Mypackage(E:java程序Mypackage),并將編譯過的class 文件放入該文件夾中。注意:包名與文件夾名大小寫要一致。再添加環(huán)境變量classpath 的路徑,例如:E:j2sdk1.4.2_01lib; E:java程序3在包中創(chuàng)建類(1)YMD.java 程序功能:在源程序中,首先聲明使用的包名Mypackag

5、e,然后創(chuàng)建YMD 類,該類具有計算今年的年份,可以輸出一個帶有年月日的字符串的功能。(2)編寫YMD.java 文件,源代碼如下。package Mypackage; /聲明存放類的包import java.util.*; /引用java.util 包public class LX4_1_YMD private int year,month,day;public static void main(String arg3)public LX4_1_YMD(int y,int m,int d) year = y;month = (m>=1) & (m<=12) ? m : 1

6、);day = (d>=1) & (d<=31) ? d : 1);public LX4_1_YMD() this(0,0,0);public static int thisyear() return Calendar.getInstance().get(Calendar.YEAR);/返回當年的年份public int year() return year;/返回年份public String toString()return year+"-"+month+"-"+day;/返回轉化為字符串的年-月-日(3)編譯LX4_1_YMD.

7、java 文件,然后將LX4_1_YMD.class 文件存放到Mypackage 文件夾中。3編寫使用包Mypackage 中LX4_1_YMD 類的程序(1)LX4_2.java 程序功能:給定某人姓名與出生日期,計算該人年齡,并輸出該人姓名,年齡,出生日期。程序使用了LX4_1_YMD 的方法來計算年齡。(2)編寫LX4_2.java 程序文件,源代碼如下。import Mypackage.LX4_1_YMD; /引用Mypackage 包中的LX4_1_YMD 類public class LX4_2private String name;private LX4_1_YMD birth;

8、public static void main(String args)LX4_2 a = new LX4_2("張馳",1990,1,11);a.output();public LX4_2(String n1,LX4_1_YMD d1)name = n1;birth = d1;public LX4_2(String n1,int y,int m,int d)this(n1,new LX4_1_YMD(y,m,d);/初始化變量與對象public int age() /計算年齡return LX4_1_YMD.thisyear() - birth.year(); /返回當前

9、年與出生年的差即年齡public void output()System.out.println("姓名 : "+name);System.out.println("出生日期: "+birth.toString();System.out.println("今年年齡 : "+age();(3)編譯并運行程序,結果如圖4.3 所示。圖4.3(三) 使用接口技術1接口的定義與作用接口可以看作是沒有實現(xiàn)的方法和常量的集合。接口與抽象類相似,接口中的方法只是做了聲明,而沒有定義任何具體的操作方法。使用接口是為了解決Java 語言中不支持多重繼承

10、的問題。單繼承可使語言本身結構簡單,層次清楚,易于管理,安全可靠,避免沖突。但同時限制了語言的功能。為了在實際應用中實現(xiàn)多重繼承的功能,Java 使用了接口技術,一個類可以實現(xiàn)多個接口以達到使用公用常量和一些常用的方法。2實現(xiàn)MouseListener 和MouseMotionListener 兩個接口(1)編寫實現(xiàn)接口的程序文件LX4_3.java,源代碼如下。import java.applet.Applet;import java.awt.*;import java.awt.event.*;public class LX4_3 extends Applet implements Mous

11、eListener, MouseMotionListener int x1, y1, x2, y2;public void init() addMouseListener(this);addMouseMotionListener(this);public void paint(Graphics g) g.drawLine (x1, y1, x2, y2);public void mousePressed(MouseEvent e) / 記錄起點坐標x1=e.getX();y1=e.getY();public void mouseClicked(MouseEvent e) public void

12、 mouseEntered(MouseEvent e) public void mouseExited(MouseEvent e) public void mouseReleased(MouseEvent e) public void mouseDragged(MouseEvent e) / 記錄終點坐標x2=e.getX();y2=e.getY();repaint();public void mouseMoved(MouseEvent e) (2)程序分析:從LX4_3 類的聲明語句中public class DrawL extends Applet implements MouseList

13、ener, MouseMotionListener可以看到使用implements 關鍵字實現(xiàn)了MouseListener 和MouseMotionListener 兩個接口。在LX4_3 類中還實現(xiàn)了MouseListener 接口中定義的5 個方法:1)public void mousePressed(MouseEvent e) / 記錄起點坐標x1=e.getX();y1=e.getY(); 2)public void mouseClicked(MouseEvent e) 3)public void mouseEntered(MouseEvent e) 4)public void mou

14、seExited(MouseEvent e) 5)public void mouseReleased(MouseEvent e) 其中只是具體實現(xiàn)了mousePressed 方法。其它都為空方法。還實現(xiàn)了MouseMotionListener 接口的兩個方法:1)public void mouseDragged(MouseEvent e) / 記錄終點坐標x2=e.getX();y2=e.getY();repaint(); 2) public void mouseMoved(MouseEvent e) 注意:在實現(xiàn)接口時,要實現(xiàn)所有接口中定義的所有方法,方法的實現(xiàn)可以具有具體的實現(xiàn)內容,也可以

15、是抽象的方法,即只有方法名或參數(shù),沒有變量、沒有具體操作語句,只有一對大括號的空方法。(3)編譯LX4_3.java 文件。(4)編寫LX4_3.html 文件,源代碼如下。<html><applet codebase=e:/java/程序code=LX4_3.class width=320 height=180></applet ></html>(5)在瀏覽器中打開LX4_3.html 文件,在窗口中拖動鼠標可以隨意畫出一條線如圖4.4 所示。圖4.4(四) 創(chuàng)建自定義接口1創(chuàng)建自定義接口的語法格式如同使用包一樣,程序員也可創(chuàng)建自定義接口。創(chuàng)建

16、自定義接口要使用聲明接口語句,格式如下:修飾符 <interface> <自定義接口名> / 靜態(tài)常量及方法聲明2創(chuàng)建自定義接口程序文件LX4_4_JK.java。(1)程序功能:在程序中聲明一個自定義接口Nl,用來計算一個人年齡。(2)編寫N1.java 程序文件,源代碼如下。interface LX4_4_JK /定義接口int year = 2004;int age();void output();說明:在LX4_4_JK 接口中聲明了兩個方法:age()和output () 以及一個整型常量year。注意:接口名首字母要大寫。3編譯LX4_4_JK.java 程

17、序文件,生成LX4_4_JK.class 文件。以后其它類即可使用LX4_4_JK接口了。4.編寫使用接口LX4_4_JK 的程序文件LX4_5.java,源代碼如下。public class LX4_5 implements LX4_4_JK /實現(xiàn)接口String xm; /類自己的成員變量(姓名)int csrq; /類自己的成員變量(出生日期)public LX4_5(String n1,int y) /類構造方法xm = n1;csrq = y;public int age() /實現(xiàn)接口的方法return year - csrq; /這里直接使用了接口中的常量yearpublic

18、void output() /實現(xiàn)接口的方法System.out.println(this.xm +"今年的年齡是"+ this.age()+"歲");public static void main (String args) /類自己的成員方法LX4_5 a = new LX4_5("張馳",1990);a.output();5編譯并運行程序,結果如圖4.5 所示。圖4.5(五) 了解異常處理機制1 錯誤與異常在程序執(zhí)行期間,會有許多意外的事件發(fā)生。例如,程序申請內存時沒有申請到、對象還未創(chuàng)建就被使用、死循環(huán)等,稱為運行錯誤。根據(jù)錯

19、誤的性質將運行錯誤分為錯誤與異常兩種類型。(1)錯誤程序進入了死循環(huán)或內存溢出,這類現(xiàn)象稱為錯誤或致命性錯誤。錯誤只能在編程階段解決,運行時程序本身無法解決,只能依靠其它程序干預,否則會一直處于一種不正常的狀態(tài)。(2)異常運算時除數(shù)為0,或操作數(shù)超出數(shù)據(jù)范圍,打開一個文件時發(fā)現(xiàn)文件不存在,網絡連接中斷等等,這類運行錯誤現(xiàn)象稱為異常。對于異常情況,可在源程序中加入異常處理代碼,當程序出現(xiàn)異常時,由異常處理代碼調整程序運行流程,使程序仍可正常運行直到正常結束。由于異常是可以檢測和處理的,所以產生了相應的異常處理機制。而錯誤處理一般由系統(tǒng)承擔。對于一個應用軟件,異常處理機制是不可缺少的。程序員必須在

20、程序中考慮每一個可能發(fā)生的異常情況并進行處理,以保證程序在任何情況下都能正常運行。事實證明,一個仔細設計了異常處理的程序,可以長時間的可靠運行,而不容易發(fā)生致命的錯誤,如程序被迫關閉、甚至系統(tǒng)終止等等。所以學會進行異常情況處理對于想編寫功能完善且具有實用價值的程序員來說是必不可少的。2 異常發(fā)生的原因(1)Java 虛擬機檢測到了非正常的執(zhí)行狀態(tài),這些狀態(tài)可能是由以下幾種情況引起的:·表達式的計算違反了Java 語言的語義,例如整數(shù)被0 除。·在載入或鏈接Java 程序時出錯。·超出了某些資源限制,例如使用了太多的內存。(2)Java 程序代碼中的throw 語句

21、被執(zhí)行。(3)異步異常發(fā)生。異步異常的原因可能有:·Thread 的stop 方法被調用。·Java 虛擬機內部錯誤發(fā)生。3異常處理機制發(fā)生異常后,怎么處理異常呢?Java 提供了異常處理機制來處理異常。分為兩個步驟:(1)拋出異常Java 是這樣規(guī)定的:當語義限制被違反時,將會拋出(throw)異常,即產生一個異常事件,生成一個異常對象,并把它提交給運行系統(tǒng),再由運行系統(tǒng)尋找相應的代碼來處理異常。一個異常對象可以由Java 虛擬機來產生,也可以由運行的方法生成。異常對象中包含了異常事件類型、程序運行狀態(tài)等必要信息。(2)捕獲異常異常拋出后,運行時系統(tǒng)從生成異常對象的代碼開

22、始,沿方法的調用棧進行查找,直到找到包含相應處理的方法代碼,并把異常對象交給該方法為止,這個過程稱為捕獲(catch)異常。簡單說異常處理機制就是:當語義限制被違反時,將會拋出異常對象,并將引起程序流程從異常發(fā)生點轉移到程序員指定的處理異常方法代碼處進行異常處理。(六) 了解異常對象的類型在異常發(fā)生后,系統(tǒng)會產生一個異常事件,生成一個異常對象,有哪些異常對象呢?這些異常對象來自哪些類呢?Java 中的異常類具有層次結構組織。其中,Throwable 類是Error 錯誤類和Exception 異常類的父類,它是Object 的直接子類。RuntimeException 運行時異常類是Excep

23、tion 異常類的子類。如圖4.6 所示。圖4.61.Exception 異常類的子類(1)RuntimeException 運行時異常類RuntimeException 類主要包括以下異常子類:·ArithmeticException 算術異常類:表示遇到了異常的算術問題,例如被0 整除。·ArrayStoreException 數(shù)組下標越界異常類:試圖把與數(shù)組類型不相符的值存人數(shù)組。·ClassCastException 類型強制轉換異常類:試圖把一個對象的引用強制轉換為不合適的類型。·IndexOutOfBoundsException 下標越界異常

24、類:下標越界。·NullPointerException 空指針異常類:試圖使用一個空的對象引用。·SecurityException 違背安全原則異常類:檢測到了違反安全的行為。(2)NoSuchMethodException 方法未找到異常(3)java.awt.AWTException 圖形界面異常類(4)java.io.TOException 輸入輸出異常類java.io.TOException 類的子類有:·IOException:申請I/O 操作沒有正常完成。·EOFException:在輸入操作正常結束前遇到了文件結束符。·Fil

25、eNotFoundException:在文件系統(tǒng)中,沒有找到由文件名字符串指定的文件。(5)Exception 異常類的其它子類·EmptyStackException:試圖訪問一個空堆棧中的元素。·NoSuchFieldException:試圖訪問一個不存在的域。·NoSuchMethodException:試圖訪問不存在的方法。·ClassNotFoundException:具有指定名字的類或接口沒有被發(fā)現(xiàn)。·CloneNotSupportedException:克隆一個沒有實現(xiàn)Cloneable 接口的類。·IllegalAcc

26、essException:試圖用給出了完整的路徑信息的字符串加載一個類,但是當前正在執(zhí)行的方法無法訪問指定類,因為該類不是public 類型或在另一個包中。·InstantiationException:試圖使用Class 的newInstance 方法創(chuàng)建一個對象實例,但指定的對象沒有被實例化,因為它是一個接口、抽象類或者一個數(shù)組。·InterruptedException:當前的線程正在等待,而另一個線程使用了Thread 的interrupt 方法中斷了當前線程。2Error 錯誤類的子類(1)VirtualMachineError 虛擬機錯誤􀁺 O

27、utOfMemoryError 內存溢出錯誤􀁺 StackOverflowError 棧溢出錯誤(2) LinkageError 鏈接錯誤􀁺 NoClassDefNotFoundError 類定義未找到錯誤(3) java.awt.AWTError 圖形界面錯誤(七) 使用trycatch 語句處理異常1異常類型匹配的處理方式( 1 ) 程序功能: 首先說明" 這是一個異常處理的例子", 然后在程序中主動產生一個ArithmeticException 類型被0 除的異常, 并用catch 語句捕獲這個異常。最后通過ArithmeticEx

28、ception 類的對象e 的方法getMessage 給出異常的具體類型并顯示出來。(2)編寫使用 trycatch 語句處理異常的程序文件LX4_6.java,源代碼如下。public class LX4_6public static void main(String arg3) System.out.println("這是一個異常處理的例子n");try int i=10;i /=0;catch (ArithmeticException e) System.out.println("異常是:"+e.getMessage();finally Syst

29、em.out.println("finally 語句被執(zhí)行");(3)編譯并運行程序,結果如圖4.7 所示。圖4.7注意:如果在catch 語句中聲明的異常類是Exception,catch 語句也能正確地捕獲,這是因為Exception 是ArithmeticException 的父類。如果不能確定會發(fā)生哪種情況的異常,那么最好指定catch的參數(shù)為Exception,即說明異常的類型為Exception。2異常類型不匹配的程序(1)編寫一個catch 語句中聲明的異常類型不匹配的程序LX4_7.java,源代碼如下。public class LX4_7public st

30、atic void main(String args) System.out.println(“這是一個異常處理的例子n”);try int i=10;i /=0;catch (IndexOutOfBoundsException e) System.out.println("異常是:"+e.getMessage();finally System.out.println("finally 語句被執(zhí)行");(2)編譯并運行程序LX4_7,結果如圖4.8 所示。因為LX4_7 程序試圖捕獲一個異常類為IndexOutOfBoundsException 的異常,

31、但發(fā)生的異常卻是ArithmeticException 類,所以,程序可以通過編譯但在運行時,系統(tǒng)會給出異常報告:報告所發(fā)生的但沒有被捕獲的異常。不過在此之前,其它語句和finally 語句將會被執(zhí)行。圖4.8提示:該程序表明,如果試圖捕獲一個不同類型的異常,將會發(fā)生意想不到的情況。3包含多個catch 子句的異常處理程序(1)程序功能:在try 子句中設計兩個可能出現(xiàn)的異常,當a 為0 時會發(fā)生異常。另外一個是肯定的異常,因為數(shù)組c 的長度為1,定義c42是為法的。通過兩個catch 子句分別來捕獲異常。(2)編寫包含多個catch 子句的LX4_8.java 程序,源代碼如下。public

32、 class LX4_8public static void main(String args) try int a=args.length;System.out.println("na = "+a);int b=42/a;int c=1;c42=99;catch (ArithmeticException e) System.out.println("發(fā)生了被 0 除:"+e);catch (ArrayIndexOutOfBoundsException e) System.out.println("數(shù)組下標越界:"+e);(2)實驗下

33、面兩種情況:1) 在程序運行時不輸入?yún)?shù),則args.length 的值為0,這將引起一個被0 除異常。其結果如圖4.9 所示。圖4.92) 在運行程序時,輸入22,將不會引起被0 除異常,但會引起一個另一個異常即數(shù)組下標越界ArrayIndexOutOfBoundsException。因為整型數(shù)組只有一個元素c0,程序中卻要使用c42,這將發(fā)生數(shù)組下標越界。運行結果如圖4.10 所示。圖4.10(八) 使用throw 語句拋出異常1 throw 語句的作用在上面的實驗中,可以發(fā)現(xiàn),異常對象是Java 運行時由系統(tǒng)拋出的。拋出異常也可以通過使用throw 語句實現(xiàn)。throw 是Java 語言

34、的關鍵字,用來告知編譯器此處要發(fā)生一個異常。throw 后面要跟一個新創(chuàng)建的異常類對象,用于指出異常的名稱和類型。throw 語句格式為:<throw> <new> <異常對象名()>程序會在throw 語句處立即終止,轉向trycatch 尋找異常處理方法,不再執(zhí)行throw 后面的語句。2 throw 語句的使用(1)編寫帶有throw 語句的程序TC5.java,源代碼如下。public class LX4_9 static void throwProcess() try throw new NullPointerException("空指針

35、異常");catch (NullPointerException e) System.out.println("n 在 throwProcess 方法中捕獲一個"+e.getMessage();throw e;public static void main(String args) try throwProcess();catch (NullPointerException e) System.out.println("再次捕獲:"+e);(2)編譯并運行程序,結果如圖4.11 所示。圖4.11(3)程序執(zhí)行流程程序首先調用throwProce

36、ss 方法,明確地拋出了一個NullPointerException 異常并將其命名為 “空指針異常”。然后程序流程將轉向throwProcess 方法中的catch 子句,輸出一條信息。throwProcess方法的catch 子句又拋出了一個同樣的異常e。然后結束throwProcess 方法的調用,執(zhí)行main 方法中的catch 子句,再次捕獲這個異常。(九) 使用throws 子句1throws 子句的作用throws 子句一般用來表明在使用該方法時可能拋出異常但不捕獲的異常。異常由系統(tǒng)來處理。throws 子句也可以指出拋出異常是RuntimeException 或自定義異常類,即

37、異常的類型,以便準備調用其它方法捕獲它,這種情況一般需要兩個方法來分別處理拋出異常和處理異常。2只是在方法中拋出異常的程序對于程序中無法處理的異常,可以使用throws 子句在方法中拋出異常交由系統(tǒng)處理。(1)程序功能:在程序中打開文件a3.txt,因為該文件可能不存在或路徑不對,所以存在IOException 類型異常的可能,因此這里使用throws 來拋出異常。(2)編寫只是拋出異常的程序文件LX4_10.java,源代碼如下。import java.io.*;public class LX4_10public static void main (String args) throws I

38、OExceptionFileInputStream fis = new FileInputStream("a3.txt");(2)編譯并運行程序,如果該文件在當前目錄中不存在,將由系統(tǒng)自動給出異常報告,如圖4.12所示。圖4.123帶有捕獲處理的throws 子句(1)程序功能:在這個程序中的mathod 方法中使用throws 子句拋出異常,在main 方法中捕獲處理異常。(2)TC6.java,源代碼如下。import java.io.*;public class LX4_11static void mathod() throws IllegalAccessExcept

39、ion System.out.println("n 在 mathod 中拋出一個異常");throw new IllegalAccessException();public static void main(String args) try mathod();catch (IllegalAccessException e) System.out.println("在 main 中捕獲異常:"+e);(3)編譯并運行程序,結果如圖4.13 所示。圖4.13(十) 使用finally 子句1 finally 子句的作用當一個異常被拋出時,程序的執(zhí)行流程就不再

40、是連續(xù)的了,會跳過某些語句,甚至會由于沒有與之匹配的catch 子句而過早地返回,結束程序的運行。為了確保一段代碼不管發(fā)生什么異常都能被執(zhí)行,可以使用finally 子句。每個try 語句至少都要有一個與之相配的catch 或finally 子句。從一個方法中返回到調用它的另外一個方法,可以通過return 語句或通過一個沒有被捕獲的異常,但finally 子句總是在返回前被執(zhí)行。2 創(chuàng)建使用finally 子句的程序文件LX4_12.java。(1)程序功能:在類LX4_12 的mathodA 方法中使用try 子句捕獲異常,使用finally 子句處理異常。在類LX4_11 的main 方法中使用try 子句捕獲mathodA 異常,(2)編寫LX4_12.java 程序,源代碼如下。class LX4_12static void mathodA() try System.out.println("nmathodA 拋出一個異常");throw new RuntimeException();finally System.out.println("執(zhí)行 matho

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論