開源俱樂部

          開源框架
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          java中goto語句解析12

          Posted on 2006-07-31 09:24 HandSoft 閱讀(17288) 評論(8)  編輯  收藏

          hi,
          ??? 今天無意中看到有個兄弟在java程序中多次用到了goto語句,感覺很是怪異,copy來編譯下發現有很多錯誤!
          為此,我付出了一下午時間去研究這個塊被人遺忘了的可怕的"魔鬼".
          ?? “可怕”的goto語句是c和c++的“遺物”,它是該語言技術上的合法部分,引用goto語句引起了程序結構的混亂,不易理解,goto語句子要用于無條件轉移子程序和多結構分支技術。鑒于以廣理由,Java不提供goto語句,它雖然指定goto作為關鍵字,但不支持它的使用,使程序簡潔易讀。在Java中goto語句被完全拋棄了,與此同時,Java又擴大了break語句和continue語句的功能,通過使用break和continue,程序流程被允許在多層循環中跳轉。
          大家再看看以下代碼:

          ?

          import java.sql.*;
          import java.util.Enumeration;
          import java.util.Vector;
          import org.apache.commons.logging.Log;
          import org.apache.commons.logging.LogFactory;

          // Referenced classes of package fiyucore.db:
          //??????????? DBOptions

          class DBConnectionManager
          {
          ??? class DBConnectionPool
          ??? {

          ??????? private String URL;
          ??????? private int checkedOut;
          ??????? private Vector freeConnections;
          ??????? private int maxConn;
          ??????? private String password;
          ??????? private String user;

          ??????? synchronized void freeConnection(Connection con)
          ??????? {
          ??????????? if(con == null)
          ??????????????? break MISSING_BLOCK_LABEL_63;
          ??????????? if(checkedOut > 0)
          ??????????????? break MISSING_BLOCK_LABEL_39;
          ??????????? DBConnectionManager.log.debug("DBConnectionManager: 關閉連接");
          ??????????? con.close();
          ????????????? goto _L1
          ??????????? SQLException ex;
          ??????????? ex;
          _L1:
          ??????????? break MISSING_BLOCK_LABEL_62;
          ??????????? freeConnections.addElement(con);
          ??????????? checkedOut--;
          ??????????? notifyAll();
          ??????????? return;
          ??????? }

          ??????? Connection getConnection(long timeout)
          ??????? {
          ??????????? long startTime = System.currentTimeMillis();
          ????????????? goto _L1
          _L3:
          ??????????? long timeToWait;
          ??????????? long elapsedTime = System.currentTimeMillis() - startTime;
          ??????????? if(elapsedTime >= timeout)
          ??????????????? return null;
          ??????????? timeToWait = timeout - elapsedTime;
          ??????????? if(timeToWait > 500L)
          ??????????????? timeToWait = 500L;
          ??????????? Thread.sleep(timeToWait);
          ??????????? continue; /* Loop/switch isn't completed */
          ??????????? InterruptedException e;
          ??????????? e;
          _L1:
          ??????????? Connection con;
          ??????????? if((con = getConnection()) == null) goto _L3; else goto _L2
          _L2:
          ??????????? return con;
          ??????? }

          ??????? synchronized Connection getConnection()
          ??????? {
          ??????????? Connection con;
          ??????????? for(con = null; freeConnections.size() > 0 && con == null;)
          ??????????? {
          ??????????????? con = (Connection)freeConnections.firstElement();
          ??????????????? freeConnections.removeElementAt(0);
          ??????????????? try
          ??????????????? {
          ??????????????????? if(con.isClosed())
          ??????????????????? {
          ??????????????????????? DBConnectionManager.log.info("刪除壞連接!");
          ??????????????????????? con = null;
          ??????????????????? }
          ??????????????? }
          ??????????????? catch(SQLException e)
          ??????????????? {
          ??????????????????? con = null;
          ??????????????? }
          ??????????? }

          ??????????? if(con == null)
          ??????????? {
          ??????????????? if(maxConn == 0 || checkedOut < maxConn)
          ??????????????????? con = newConnection();
          ??????????? }
          ??????????? if(con != null)
          ??????????????? checkedOut++;
          ??????????? return con;
          ??????? }

          ??????? private Connection newConnection()
          ??????? {
          ??????????? Connection con = null;
          ??????????? if(user == null)
          ??????????????? con = DriverManager.getConnection(URL);
          ??????????? else
          ??????????????? con = DriverManager.getConnection(URL, user, password);
          ??????????? con.setAutoCommit(true);
          ??????????? break MISSING_BLOCK_LABEL_83;
          ??????????? SQLException e;
          ??????????? e;
          ??????????? DBConnectionManager.log.error("不能在連接池中創建新的連接. URL = " + URL, e);
          ??????????? return null;
          ??????????? return con;
          ??????? }

          ??????? synchronized boolean release()
          ??????? {
          ??????????? boolean retValue;
          ??????????? Enumeration allConnections;
          ??????????? retValue = true;
          ??????????? allConnections = freeConnections.elements();
          ????????????? goto _L1
          _L3:
          ??????????? Connection con = (Connection)allConnections.nextElement();
          ??????????? con.close();
          ??????????? continue; /* Loop/switch isn't completed */
          ??????????? SQLException e;
          ??????????? e;
          ??????????? DBConnectionManager.log.error("不能關閉連接!");
          _L1:
          ??????????? if(allConnections.hasMoreElements()) goto _L3; else goto _L2
          _L2:
          ??????????? freeConnections.removeAllElements();
          ??????????? if(checkedOut != 0)
          ??????????? {
          ??????????????? retValue = false;
          ??????????????? DBConnectionManager.log.warn("DBConnectionManager: 內置的連接池沒有正確配置好");
          ??????????? }
          ??????????? checkedOut = 0;
          ??????????? return retValue;
          ??????? }

          ??????? public DBConnectionPool(String URL, String user, String password, int maxConn)
          ??????? {
          ??????????? checkedOut = 0;
          ??????????? freeConnections = new Vector();
          ??????????? this.maxConn = 0;
          ??????????? this.password = null;
          ??????????? this.URL = null;
          ??????????? this.user = null;
          ??????????? this.URL = URL;
          ??????????? this.user = user;
          ??????????? this.password = password;
          ??????????? this.maxConn = maxConn;
          ??????? }
          ??? }


          ??? private static final int TIME_BETWEEN_RETRIES = 500;
          ??? static Class class$fiyucore$db$DBConnectionManager; /* synthetic field */
          ??? private static DBConnectionManager instance = null;
          ??? private static Log log;
          ??? private DBConnectionPool pool;

          ??? private DBConnectionManager(DBOptions option)
          ??? {
          ??????? pool = null;
          ??????? Class.forName(option.driverClassName).newInstance();
          ??????? break MISSING_BLOCK_LABEL_59;
          ??????? Exception e;
          ??????? e;
          ??????? log.fatal("DBConnectionManager: 不能加載驅動 = " + option.driverClassName);
          ??????? pool = new DBConnectionPool(option.databaseURL, option.databaseUser, option.databasePassword, option.maxConnection);
          ??????? return;
          ??? }

          ??? static Class class$(String x0)
          ??? {
          ??????? return Class.forName(x0);
          ??????? ClassNotFoundException x1;
          ??????? x1;
          ??????? throw new NoClassDefFoundError(x1.getMessage());
          ??? }

          ??? void freeConnection(Connection con)
          ??? {
          ??????? pool.freeConnection(con);
          ??? }

          ??? Connection getConnection(long time)
          ??? {
          ??????? return pool.getConnection(time);
          ??? }

          ??? Connection getConnection()
          ??? {
          ??????? return pool.getConnection();
          ??? }

          ??? public static synchronized DBConnectionManager getInstance(DBOptions option)
          ??? {
          ??????? if(instance == null)
          ??????? {
          ??????????? if(option == null)
          ??????????????? option = new DBOptions();
          ??????????? instance = new DBConnectionManager(option);
          ??????? }
          ??????? return instance;
          ??? }

          ??? public static synchronized DBConnectionManager getInstance()
          ??? {
          ??????? if(instance == null)
          ??????? {
          ??????????? DBOptions option = new DBOptions();
          ??????????? instance = new DBConnectionManager(option);
          ??????? }
          ??????? return instance;
          ??? }

          ??? boolean release()
          ??? {
          ??????? return pool.release();
          ??? }

          ??? static
          ??? {
          ??????? log = LogFactory.getLog(class$fiyucore$db$DBConnectionManager != null ? class$fiyucore$db$DBConnectionManager : (class$fiyucore$db$DBConnectionManager = class$("fiyucore.db.DBConnectionManager")));
          ??? }

          }
          這程序初看起來是多么的恐怖啊!多次用到goto,混亂。關于流程控制的方法,c++,java都提供了很好的語法:

        1. 分支語句 :if-else,break,switch, return.
        2. 循環語句 :while,do-while,for, continue.
        3. 例外處理語句 :try-catch-finally,throw
        4. 最后我們簡單介紹一下注釋語句
        5. 支語句

          分支語句提供了一種控制機制,使得程序的執行可以跳過某些語句不執行,而轉去執行特定的語句。

          條件語句if-else.

          if-else語句根據判定條件的真假來執行兩種操作中的一種,格式為:

          if(boolean-expression)
          statement1;
          [else statement2;]


          1.布爾表達式boolean-expression是任意一個返回布爾型數據的達式(這比C、 C++的限制要嚴格)。

          2.每個單一的語句后都必須有分號。

          3.語句statement1,statement2可以為復合語句,這時要用大括號{}。建議對單一的語句也用大括號括起,這樣程序的可讀性強,而且有利于程序的擴充(可以在其中填加新的語句)。{}外面不加分號。

          4.else子句是任選的。

          5.若布爾表達式的值為true,則程序執行statement1,否則執行statement2。

          6.if-else語句的一種特殊形式為:

          if(expression1){?
          statement1?
          }else if (expression2){?
          statement2?
          }……?
          }else if (expressionM){?
          statementM?
          }else {?
          statementN?
          }?
          [else子句不能單獨作為語句使用,它必須和if配對使用。else總是與離它最近的if配對。可以通過使用大括號{}來改變配對關系。]
          多分支語句switch

          switch語句根據表達式的值來執行多個操作中的一個,它的般格式如下:

          switch (expression){
          casevalue1:statement1;
          break;
          casevalue2:statement2;
          break;
          …………
          casevalueN:statemendN;
          break;
          [default:defaultStatement;]
          }


          1.表達式expression可以返回任一簡單類型的值(如整型、實數型、字符型),多分支語句把表達式返回的值與每個case子句中的值相比。如果匹配成功,則運行該case子句后的語句序列。

          2.case子句中的值values必須是常量,而且所有case子句中的值是不同的。

          3.default子句是任選的。當表達式的值與任一case子句中的都不匹配時,程序執行default后面的語句。如果表達式的值與任一case子句中的值都不匹配且沒有default子句,則程序不作任何操作,而是直接跳出switch語句。

          4.break語句用來在執行完一個case分支后,使程序跳出switch語句,即終止switch語句的執行。因為case子句只是起到一個標號的作用,用來查找匹配的入口,從此處開始執行,對后面的case子句不再進行匹配,而是直接執行其后的語句序列,因此該在每個case分支后,要用break來終止后面的case分支語句的執行。

          在一些特殊情況下,多個不同的case值要執行一組相同的操作,這時可以不用break。

          5.case分支中包括多個執行語句時,可以不用大括號{}括起。

          6.switch語句的功能可以用if-else來實現,但在某些情況下,使switch語句更簡煉,可讀性強,而且程序的執行效率提高。
          break語句

          1.在switch語中,break語句用來終止switch語句的執行。使程序switch語句后的第一個語句開始執行。

          2.在Java中,可以為每個代碼塊加一個括號,一個代碼塊通常用大括號{}括起來的一段代碼。加標號的格式如下:

          BlockLabel:{codeBlock}

          break語句的第二種使用情況就是跳出它所指定的塊,并從緊挨該塊的第一條語句處執行。其格式為:

          break BlockLabel;
          例如:
          a:{……//標記代碼塊a
          b:{……//標記代碼塊b
          c:{……//標記代碼塊c
          break b;
          …… //willnotbeexecuted
          }
          …… //willnotbeexecuted
          }
          …… //willnotbeexecuted
          }
          …… /executefromhere
          }


          3.與C、 C++不同,Java中沒有goto語句來實現任意的跳轉,因為goto語句破壞程序的可讀性,而且影響編譯的優化。但是從上例可以看出,Java用break來實現goto語句所特有的一些優點。如果break后所指定的標號不是一個代碼塊的標號,而是一個語句,則這時break完全實現goto的功能。不過應該避免這種方式的使用。
          返回語句return

          return語句從當前方法中退出,返回到調用該方法的語句處,繼續程序的執行。返回語句有兩種格式:


          1.return expression

          返回一個值給調用該方法的語句,返回值的數據類型必須用方法聲明中的返回值類型一致。可以使用強制類型轉換來使類型一致。

          2.return

          當方法說明中用void聲明返回類型為空時,應使用這種格式,不返回任何值。

          return語句通常用在一個方法體的最后,以退出該方法并返一個值。Java中,單獨的return語句用在一個方法體的中間時,會產生編譯錯誤,因為這時有一些語句執行不到。但
          可以通過把return語句嵌入某些語句(如if-else)來使程序在未執行完方法中的所有語句時退出,例如:

          int method (int num) {?
          ∥ return num; ∥will cause compile time error?
          if (num>0)?
          return num;?
          …… ∥ may or may not be executed?
          ∥depending on the value of num?
          環語句

          循環語句的作用是反復執行一段代碼,直到滿足終止循環條件為止,一個循環一般應包括四部分內容:

          1.初始化部分(initialization):用來設置循環的一些初始條件,計數器清零等。

          2.循環體部分(body):這是反復循環的一段代碼,可以是單一一條語句,也可以是復合語句。

          3.迭代部分(iteration):這是在當前循環結束,下一次循環開始執行的語句,常常用來使計數器加1或減1。

          4.終止部分(termination):通常是一個布爾表達式,每一次循環要對該表達式求值,以驗證是否滿足循環終止條件。

          Java中提供的循環語句有:while語句,do-while語句和for語句,下分別介紹。
          while語句

          while語句實現"當型"循環,它的一般格式為;

          [initialization]
          while (termination){
          body;
          [iteration;]
          }


          1.當布爾表達式(termination)的值為true時,循環執行大括號中語句。并且初始化部分和迭代部分是任選的。

          2.while語句首先計算終止條件,當條件滿足時,才去執行循環當中的語句。這是"當型"循環的特點。


          do-while語句

          do-while語句實現"直到型"循環,它的一般格式為:
          [initialization]
          do{
          body;
          [iteration;]
          }while (termination);


          1.do-while語句首先執行循環體,然后計算終止條件,若結果為true,則循環執行大括號中的語句,直到布爾表達式的結果為false。

          2.與while語句不同的是,do-while語句的循環體至少執行一次,這是"直到型"循環的特點。
          for語句

          for語句也用來實現"當型"循環,它的一般格式為:

          for(initialization;termination; iteration){

          body;

          }

          1.for語句執行時,首先執行初始化操作,然后判斷終止條件否滿足,如果滿足,則執行循環體中的語句,最后執行迭代部分。完成一次循環后,重新判斷終止條件。

          2.可以在for語句的初始化部分聲明一個變量,它的作用域為一個for語句。

          3.for語句通常用來執行循環次數確定的情況(如對數組元素進行操作),也可以根據循環結束條件執行循環次數不確定的情況。

          4.在初始化部分和迭代部分可以使用逗號語句,來進行多個操作。逗號語句是用逗號分隔的語句序列。例如:

          for(i=0,j=10;i<j;i++, j--){
          ……
          }
          5.初始化、終止以及迭代部分都可以為空語句,三者均為空的時候,相當于一個無限循環。


          continue語句

          1.continue語句用來結束本次循環,跳過循環體中下面尚未執的語句,接著進行終止條件的判斷,以決定是否繼續循環。對于for語句,在進行終止條件判斷前,還要先執行迭代
          語句。它的格式為:

          continue;
          2.也可以用continue跳轉到括號指明的外層循環中,這時的格為

          continue outerLable;?

          例 如 :?

          outer: for( int i=0; i<10; i++ ){ ∥外層循環?
          for( int j=0; j<20; j++ ){ ∥內層循環?
          if( j>i ){?
          ……?
          continue outer;?
          }?
          ……?
          }?
          ……?
          }?


          該例中,當滿足j>i的條件時,程序執行完相應的語句后跳轉到外層循環,執行外層循環的迭代語句i++;然后開始下一次循環。
          可以從中來比較這三種循環語句,從而在不同的場合選擇合適的語句。
          外處理語句

          例外處理語句包括try、catch、finally以及throw語句

          釋語

          Java中可以采用三種注釋方式:

          1∥ 用于單行注釋。注釋從∥開始,終止于行尾。
          2/*…*/用于多行注釋。注釋從/*開始,到*/結束,且這種注釋不能互相嵌套。
          3/**…*/是Java所特有的doc注釋。它以/**開始,到*/結束。這種注釋主要是為支持JDK工具javadoc而采用的。javadoc能識別注釋中用標記@標識的一些特殊變量,并把doc注釋加入它所生成的HTML文件。


          評論

          # re: java中goto語句解析12  回復  更多評論   

          2007-04-10 17:23 by 沒所謂
          這段代碼是我們公司的一段極相似, 而且照常運行,

          # re: java中goto語句解析12  回復  更多評論   

          2007-08-22 19:58 by sisi
          能不能請樓主解釋下,為什么上面的程序會出現使用goto語句的情況?還有,到底在java中可不可以使用goto語句?

          # re: java中goto語句解析12  回復  更多評論   

          2008-02-05 17:56 by wl
          因為這個代碼是用反編譯得來的。

          # re: java中goto語句解析12  回復  更多評論   

          2008-03-03 15:30 by vanslyke
          碰到過類似問題
          源代碼中是不存在goto的
          是反編譯出來的結果

          # re: java中goto語句解析12  回復  更多評論   

          2008-08-26 18:01 by
          確實是反編譯的結果,JAVA中如果有GOTO語法那就是新聞了.

          # re: java中goto語句解析12[未登錄]  回復  更多評論   

          2008-09-18 09:40 by test
          你這篇goto的“解析”應該叫替代goto的方法,文不對題

          # re: java中goto語句解析12  回復  更多評論   

          2008-09-25 11:43 by 小寧
          不明白GOTO的請不要亂參與發表意見啊
          菜鳥才不會用
          Java 中雖然沒有GOTO 關鍵字
          但是依然保留了用法
          好的GOTO語句不僅僅可以使程序變的更加靈活
          也可以做一些BREAK,CONTINUE所做不到的!
          菜鳥不用并不代表高手不用!

          # re: java中goto語句解析12  回復  更多評論   

          2013-03-15 11:38 by chn
          餓。。。我反編譯了代碼里面很多的goto.但是我想問的是怎么讓他們編譯通過?@小寧

          只有注冊用戶登錄后才能發表評論。


          網站導航:
          博客園   IT新聞   Chat2DB   C++博客   博問  
           
          主站蜘蛛池模板: 福泉市| 克东县| 洪洞县| 建阳市| 若尔盖县| 久治县| 邯郸市| 晋州市| 农安县| 漾濞| 博乐市| 中超| 昭通市| 自贡市| 新沂市| 清流县| 留坝县| 乐平市| 娄烦县| 铜鼓县| 河北省| 玉环县| 宣威市| 金坛市| 桂东县| 斗六市| 友谊县| 巩义市| 个旧市| 威宁| 木里| 门头沟区| 唐海县| 沁源县| 阿勒泰市| 华容县| 钟祥市| 呼伦贝尔市| 麻栗坡县| 琼海市| 平度市|