簡體   English   中英

Java編譯混亂:為什么要編譯此代碼?

[英]Java compilation confusion: why does this code compile?

我不確定為什么此代碼(在運行時提供stackoverflow)會編譯:

import java.io.*;
import java.util.*;

public class StackOverflow {
   StackOverflow overflow = new StackOverflow();

   public void myCall() {
       overflow.myPrint();
   }

   public static void main(String[] args) {
       StackOverflow newStackOverflow = new StackOverflow();
       newStackOverflow.myCall();
   }

   public void myPrint() {
       System.out.println("I am confused!");
   }
}

我感到困惑的原因是,在類定義中,我試圖創建要定義的類的對象。 這不是編譯時錯誤嗎?

這不是編譯時錯誤,因為編譯器無法確定它是否將在編譯時無限生成。

您和我可以查看並確定看到它,但是編譯器只關心聲明是正確的。 該聲明在語法上沒有任何非法之處,這就是為什么編譯器將其放任不管。

它與停止問題有關 ,因為程序無法報告是否成功停止。

我想可以認為,編譯器應捕獲此無限循環的遞歸版本,但是語言定義中沒有任何內容使對象在實例化時構造其自身的另一個實例是非法的。

我當然希望像FindBugs這樣的代碼分析工具會抱怨。

不,這不是Java的問題。 動態聲明非常快速和寬松,不需要在使用之前聲明它們。 稍后再進行說明,並使該語言更易於使用。

它為您提供了堆棧溢出異常,因為每次創建StackOverflow時,該行

StackOverflow overflow = new StackOverflow();

創建另一個StackOverflow,再創建另一個StackOverflow,依此類推,直到堆棧最大化並引發異常。

不會。Java不會在編譯時檢測無限循環或無限遞歸。 您可以像下面這樣編譯您的代碼或下面的方法,它將在運行時崩潰。

 private int recurseForever(){
     return recurseForever();
 }

在您的情況下,構造函數將創建該類的新實例,從而調用另一個構造函數,依此類推。

至於為什么它不這樣做:因為不可能在所有情況下都這樣做(停止問題),並且無法將資源投入到部分解決方案中(這僅在某些時候起作用,但總是對每個人都降低了編譯速度,可能還引入了錯誤)因為現在編譯器更加復雜),顯然不是一個好主意。

由於編譯器實際上不可能捕獲您可以做到的所有可能方式,因此不需要編譯器捕獲它。 通常,無限遞歸只能在運行時檢測到。 (即使那樣,您仍然可以檢測到它超出了允許的限制。)

我感到困惑的原因是,在類定義中,我試圖創建要定義的類的對象。 這不是編譯時錯誤嗎?

當編譯器看到這段代碼時,您已經完全定義了您的類,並且編譯器可以毫不含糊地創建此類的對象。 因此,這表明沒有編譯時錯誤。

不,它不應該通過編寫以下代碼行來產生錯誤: StackOverflow overflow = new StackOverflow(); 您實際上是在類中創建實例變量。 這行StackOverflow newStackOverflow = new StackOverflow(); 將創建您的局部變量。

如果您按照以下方式更新代碼,那么它也將起作用。

import java.io.*;
import java.util.*;

public class StackOverflow {
   private static StackOverflow overflow = new StackOverflow();

   public void myCall() {
       overflow.myPrint();
   }

   public static void main(String[] args) {
       overflow.myCall();
   }

   public void myPrint() {
       System.out.println("I am confused!");
   }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM