无法从静态上下文引用非静态方法

我想一劳永逸地理解这一点。

有了这个,请原谅下面粘贴的大量代码,但我不想遗漏任何细节。

我唯一改变的是加载的URL。 但这不会导致错误。

我想把我的function称为“ 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 hashPositions=new HashMap(); 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; } } 

真正的解决方 不要在main()方法中放入太多东西。 这是为了新手。

Java是一种面向对象的语言。 将逻辑放在与GarageComm类关联的方法中。 main()应该只是实例化一个实例并调用它的方法。

像这样改变它:

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

这是新Java程序员的典型思维导向器。

static方法不属于对象。 非static方法属于对象。

您使用main -method约定来启动程序,并且该方法必须是静态的。

static方法到非static方法的技巧是,您必须创建一个对象,以便可以调用该方法。 即new GarageComm().readPositions(...) 。 我只是觉得你不必在这里,所以将readPositions标记为静态也会更简单。

你需要让你的函数静态:

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

创建GarageComm的实例也会起作用,但这在Java中是不好的编程实践,因为该对象没有状态。

如果方法不是静态的,则必须在对象上“调用”它。 从非静态方法调用方法时,隐含该对象 – 它是调用第一个方法的对象。 但是当从静态方法调用它时,没有隐含的对象,因此要调用该方法,必须提供一个对象:

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

由于GarageComm没有自己的状态,因此没有理由创建GarageComm对象,所以你也可以将方法标记为static,因此不需要任何对象来调用它。

在这种情况下,将方法设为静态是一个好主意。 另一种方式是使用

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

代替。

那么,为什么这个错误呢?

静态方法不能在同一个类中调用非静态方法。 这听起来很奇怪,但这是有道理的。 考虑一下:

  • 非静态方法可能取决于对象的状态,即实例变量。

  • 可以从外部调用静态方法而无需实例化

现在,如果我们允许静态方法使用非静态方法(和非静态变量),它们可能会失败。 所以,这是一种预防。

我什么时候应该考虑使方法静态?

现在,来, 为什么不让方法static

很好,如果它的function不依赖于对象的状态,你应该使方法静态。

如果它只是使用传递的参数和一些静态的东西(静态变量,静态方法)和返回(有/没有结果,抛出exception的东西),考虑使它成为静态方法。


更新:看起来像这个post困惑了几个人所以更新了答案。