2011-05-12 121 views
3

我想一勞永逸地理解這一點。非靜態方法不能從靜態上下文中引用

有了這個,請原諒大量的代碼粘貼在下面,但我不想忽略任何細節。

我改變的唯一的事情就是加載的URL。但是這不會導致錯誤。

我想打電話給我的功能「readPosiitons」。簡單的解決方案,使其靜態。真正的解決方案,我不確定。

請幫助我更好地瞭解如何以正確的方式解決此錯誤。

謝謝!

  /* 
      * To change this template, choose Tools | Templates 
      * and open the template in the editor. 
      */ 

      package PandL; 

      import java.io.BufferedReader; 
      import java.io.File; 
      import java.io.IOException; 
      import java.io.InputStreamReader; 
      import java.net.MalformedURLException; 
      import java.net.URL; 
      import java.util.HashMap; 
      import java.util.Scanner; 
      import toolBox.Secretary; 
      import toolBox.Secretary.positionObj; 

      /** 
      * 
      * @author Jason 
      * 
      */ 
      public class GarageComm { 
       public static void main(String[] args) throws MalformedURLException, IOException{ 
        String retStr; 
        String startM; 
        String endM; 
        String myURL; 
        String[] Split1=null; 
        Integer lnCount; 
        HashMap hashPos=new HashMap(); 
        hashPos= readPositions("holdingsBU.txt");//the error is here 

        myURL="http://myUrl?s="; 

        URL url = new URL(myURL); 
        BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); 



        in.close(); 
       } 

       public HashMap readPositions(String destFile){ 

        HashMap<String, Secretary.positionObj> hashPositions=new HashMap<String,positionObj>(); 
        Secretary mySecretary=new Secretary(); 
        try{ 
         File F=new File(destFile); 
         if(F.exists()){ 
          System.out.println("File Exists: "+F.exists()); 
          System.out.println(destFile); 
          Scanner sC= new Scanner(F); 

          while (sC.hasNext()){ 
           String[] Splitter1; 
           Secretary.positionObj position=mySecretary.new positionObj(); 


           Splitter1=sC.nextLine().split(","); 
           position.positionDate=Double.parseDouble(Splitter1[0]); 
           position.positionTicker=(Splitter1[1]); 
           position.positionOpen=Double.parseDouble(Splitter1[2]); 
           position.positionPrice=Double.parseDouble(Splitter1[3]); 
           position.positionSMA=Double.parseDouble(Splitter1[4]); 
           position.positionUpdated=Double.parseDouble(Splitter1[5]); 
           position.priceUpdated=Double.parseDouble(Splitter1[6]); 
           position.updateDate=Double.parseDouble(Splitter1[7]); 


           hashPositions.put(position.positionTicker.trim(), position); 

          } 


         }else{ 
          System.out.println("File Created: "+ F.createNewFile()); 
          System.out.println("----No previous positions----"); 
         } 

        }catch (Exception E){ 
         System.err.println(destFile + " does not exist."); 
         hashPositions.put("ERROR", null); 
         E.printStackTrace(); 
        } 
        return hashPositions; 
       } 
      } 
+0

你問*爲什麼*你必須聲明它'靜態'? – rlibby 2011-05-12 02:46:23

回答

2

真正的解決方案?不要把這麼多東西放在main()方法中。這是爲了noobs。

Java的一種面向對象的語言。將邏輯放在與GarageComm類關聯的方法中。 main()只應該實例化一個實例並調用它的方法。

改變這樣的:

  GarageComm gc = new GarageComm(); 
      hashPos= gc.readPositions("holdingsBU.txt");//the error is here 
0

在這種情況下,使方法變爲靜態是一個好主意。另一種方法是使用

new GarageComm().readPositions("holdingsBU.txt") 

代替。

那麼,爲什麼這個錯誤呢?

靜態方法無法在同一個類中調用非靜態方法。這聽起來很奇怪,但有一個原因。試想一下:

  • 非靜態方法可以取決於對象的狀態,實例變量的話。

  • 靜態方法可以從外側被稱爲無instanciating

現在,如果我們允許靜態方法與非靜態方法(和非靜態變量)玩,他們威力失敗。所以,這是一種預防。

什麼時候應該考慮讓方法變爲靜態?

現在,來吧,爲什麼不製作方法static,

很好,你應該使一個方法靜態,如果它的功能不依賴於對象的狀態。

如果它只是使用傳遞的參數和一些靜態東西(靜態變量,靜態方法)並返回(帶/不帶結果,拋出異常),可以考慮使它成爲靜態方法。


更新:這個樣子迷惑後一對夫婦的人,所以更新的答案。

1

你需要讓你的函數靜:

public static HashMap readPositions(String destFile) { 
... 
} 

創建GarageComm的一個實例,將工作太,但這是在Java中不好的編程習慣,因爲這個對象沒有狀態。

+0

這不是一個壞習慣。這只是一個糟糕的解決方案。不要成爲純粹主義者;讓它起作用。 – duffymo 2011-05-12 02:52:57

+1

@duffymo不好的做法和做得不好的解決方案有什麼區別?我不明白你的意思...... – JVerstry 2011-05-12 02:54:58

+0

一個不好的做法是,你建議某個人是一個優秀的程序員。這似乎是一個正在學習如何編寫代碼的人,因爲對於任何瞭解Java的人來說,這應該是一個很容易的錯誤。所以我的建議就是讓它工作,即使對象設計不完美。設計是一種習慣於語法的技巧。這個人還沒有到那個時候。 – duffymo 2011-05-12 02:58:08

0

如果方法不是靜態的,那麼它必須被稱爲「上」的對象。當從非靜態方法調用方法時,該對象是隱含的 - 它是第一個方法被調用的對象。但是,從一個靜態方法調用它時,不存在隱含的對象,因此要調用的方法,你必須提供一個對象:

GarageComm gc = new GarageComm(); 
hashPos= gc.readPositions("holdingsBU.txt"); 

由於GarageComm沒有自己的狀態,沒有理由創造GarageComm對象,所以你只需將方法標記爲靜態,所以不需要對象來調用它。

+0

靜態方法不需要在對象實例上調用.... – JVerstry 2011-05-12 02:51:29

+0

@JVestry - 愚蠢的錯字,修正。 – 2011-05-12 02:52:46

2

這是一個新的Java程序員的典型mindbender。

A static方法不屬於一個對象。非static方法屬於對象。

使用main -method約定來啓動程序,並且要求該方法必須是靜態的。

static方法到非static方法的訣竅是您必須創建一個對象,以便您可以調用該方法。即new GarageComm().readPositions(...)。我只是不認爲你必須在這裏,所以將readPositions標記爲靜態會更簡單。

相關問題