2011-05-12 127 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标记为静态会更简单。

相关问题