Java “不能从静态上下文中引用非静态方法”背后的原因是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/290884/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the reason behind "non-static method cannot be referenced from a static context"?
提问by DragonBorn
The very common beginner mistake is when you try to use a class property "statically" without making an instance of that class. It leaves you with the mentioned error message:
非常常见的初学者错误是当您尝试“静态”使用类属性而不创建该类的实例时。它给您留下了提到的错误消息:
You can either make the non static method static or make an instance of that class to use its properties.
您可以将非静态方法设为静态或创建该类的实例以使用其属性。
Why? I am not asking for solutions. I would be grateful to know what is the reason behind it. The very core reason!
为什么?我不是在寻求解决方案。我会很感激知道它背后的原因是什么。最核心的原因!
private java.util.List<String> someMethod(){
/* Some Code */
return someList;
}
public static void main(String[] strArgs){
// The following statement causes the error. You know why..
java.util.List<String> someList = someMethod();
}
采纳答案by Brian Knoblauch
You can't call something that doesn't exist. Since you haven't created an object, the non-static method doesn't exist yet. A static method (by definition) always exists.
你不能调用不存在的东西。由于您尚未创建对象,因此非静态方法尚不存在。静态方法(根据定义)始终存在。
回答by Steven A. Lowe
The method you are trying to call is an instance-level method; you do not have an instance.
您尝试调用的方法是实例级方法;你没有实例。
static
methods belong to the class, non-static
methods belong to instances of the class.
static
方法属于类,非static
方法属于类的实例。
回答by Robin
A static method relates an action to a type of object, whereas the non static method relates an action to an instance of that type of object. Typically it is a method that does something with relation to the instance.
静态方法将动作与对象类型相关联,而非静态方法将动作与该类型对象的实例相关联。通常,它是一种与实例相关的方法。
Ex:
前任:
class Car might have a wash method, which would indicate washing a particular car, whereas a static method would apply to the type car.
类 Car 可能有一个 Wash 方法,该方法将指示清洗特定的汽车,而静态方法将应用于类型 car。
回答by Charles Bretana
if a method is not static, that "tells" the compiler that the method requires access to instance-level data in the class, (like a non-static field). This data would not be available unless an instance of the class has been created. So the compiler throws an error if you try to call the method from a static method.. If in fact the method does NOT reference any non-static member of the class, make the method static.
如果方法不是静态的,则“告诉”编译器该方法需要访问类中的实例级数据(如非静态字段)。除非创建了类的实例,否则此数据将不可用。因此,如果您尝试从静态方法调用该方法,编译器会抛出错误。如果实际上该方法不引用该类的任何非静态成员,则将该方法设为静态。
In Resharper, for example, just creating a non-static method that does NOT reference any static member of the class generates a warning message "This method can be made static"
例如,在 Resharper 中,只需创建一个不引用类的任何静态成员的非静态方法就会生成警告消息“此方法可以设为静态”
回答by Ande Turner
The answers so far describe why, but here is a something else you might want to consider:
到目前为止的答案描述了原因,但这里还有一个你可能需要考虑的事情:
You can can call a method from an instantiable class by appending a method call to its constructor,
您可以通过将方法调用附加到其构造函数来从可实例化类调用方法,
Object instance = new Constuctor().methodCall();
or
或者
primitive name = new Constuctor().methodCall();
This is useful it you only wish to use a method of an instantiable class once within a single scope. If you are calling multiple methods from an instantiable class within a single scope, definitely create a referable instance.
如果您只想在单个范围内使用一次可实例化类的方法,这很有用。如果您在单个范围内从可实例化的类调用多个方法,请务必创建一个可引用的实例。
回答by Hugo
I just realized, I think people shouldn't be exposed to the concept of "static" very early.
我刚刚意识到,我认为人们不应该很早就接触到“静态”的概念。
Static methods should probably be the exception rather than the norm. Especially early on anyways if you want to learn OOP. (Why start with an exception to the rule?) That's very counter-pedagogical of Java, that the "first" thing you should learn is the public staticvoid main thing. (Few real Java applications have their own main methods anyways.)
静态方法应该是例外而不是常态。如果你想学习 OOP,尤其是在早期。(为什么从规则的例外开始?)这是 Java 的非常反教学法,您应该学习的“第一”件事是 public staticvoid 主要内容。(无论如何,很少有真正的 Java 应用程序有自己的主要方法。)
回答by Hugo
The compiler actually adds an argument to non-static methods. It adds a this pointer/reference. This is also the reason why a static method can not use this
, because there is no object.
编译器实际上为非静态方法添加了一个参数。它添加了this pointer/reference. This is also the reason why a static method can not use this
, 因为没有对象。
回答by Michael Borgwardt
The essence of object oriented programming is encapsulating logic together with the data it operates on.
面向对象编程的本质是将逻辑与其操作的数据一起封装。
Instance methods are the logic, instance fields are the data. Together, they form an object.
实例方法是逻辑,实例字段是数据。它们一起形成一个对象。
public class Foo
{
private String foo;
public Foo(String foo){ this.foo = foo; }
public getFoo(){ return this.foo; }
public static void main(String[] args){
System.out.println( getFoo() );
}
}
What could possibly be the result of running the above program?
运行上述程序的结果可能是什么?
Without an object, there is no instance data, and while the instance methods exist as part of the class definition, they need an object instance to provide data for them.
没有对象,就没有实例数据,虽然实例方法作为类定义的一部分存在,但它们需要一个对象实例来为它们提供数据。
In theory, an instance method that does not access any instance data could work in a static context, but then there isn't really any reason for it to be an instance method. It's a language design decision to allow it anyway rather than making up an extra rule to forbid it.
理论上,不访问任何实例数据的实例方法可以在静态上下文中工作,但实际上没有任何理由让它成为实例方法。无论如何,允许它是一种语言设计决定,而不是制定额外的规则来禁止它。
回答by Vipul
The simple reason behind this is that Static data members of parent class can be accessed (only if they are not overridden) but for instance(non-static) data members or methods we need their reference and so they can only be called through an object.
这背后的简单原因是可以访问父类的静态数据成员(仅当它们未被覆盖时)但例如(非静态)数据成员或方法我们需要它们的引用,因此它们只能通过对象调用.
回答by Erik Eidt
I think it is worth pointing out that by the rules of the Java language the Java compiler inserts the equivalent of "this." when it notices that you're accessing instance methods or instance fields without an explicit instance. Of course, the compiler knows that it can only do this from within an instance method, which has a "this" variable, as static methods don't.
我认为值得指出的是,根据 Java 语言的规则,Java 编译器插入了“this”的等价物。当它注意到您正在访问没有显式实例的实例方法或实例字段时。当然,编译器知道它只能从具有“this”变量的实例方法中执行此操作,而静态方法则没有。
Which means that when you're in an instance method the following are equivalent:
这意味着当您使用实例方法时,以下内容是等效的:
instanceMethod();
this.instanceMethod();
and these are also equivalent:
这些也是等价的:
... = instanceField;
... = this.instanceField;
The compiler is effectively inserting the "this." when you don't supply a specific instance.
编译器有效地插入了“this”。当您不提供特定实例时。
This (pun intended) bit of "magic help" by the compiler can confuse novices: it means that instance calls and static calls sometimes appear to have the same syntax while in reality are calls of different types and underlying mechanisms.
编译器的这个(双关语)“魔法帮助”可能会让新手感到困惑:这意味着实例调用和静态调用有时看起来具有相同的语法,而实际上是不同类型和底层机制的调用。
The instance method call is sometimes referred to as a method invocation or dispatch because of the behaviors of virtual methods supporting polymorphism; dispatching behavior happens regardless of whether you wrote an explicit object instance to use or the compiler inserted a "this.".
由于支持多态的虚方法的行为,实例方法调用有时被称为方法调用或分派;无论您是编写了要使用的显式对象实例还是编译器插入了“this.”,都会发生分派行为。
The static method call mechanism is simpler, like a function call in a non-OOP language.
静态方法调用机制更简单,就像非OOP语言中的函数调用。
Personally, I think the error message is misleading, it could read "non-static method cannot be referenced from a static context without specifying an explicit object instance".
就我个人而言,我认为该错误消息具有误导性,它可能是“在不指定显式对象实例的情况下,不能从静态上下文中引用非静态方法”。
What the compiler is complaining about is that it cannot simply insert the standard "this." as it does within instance methods, because this code is within a static method; however, maybe the author merely forgot to supply the instance of interest for this invocation — say, an instance possibly supplied to the static method as parameter, or created within this static method.
编译器抱怨的是它不能简单地插入标准的“this”。就像在实例方法中一样,因为此代码在静态方法中;然而,也许作者只是忘记为这个调用提供感兴趣的实例——比如说,一个可能作为参数提供给静态方法的实例,或者在这个静态方法中创建的实例。
In short, you most certainly can call instance methods from within a static method, you just need to have and specify an explicit instance object for the invocation.
简而言之,您肯定可以从静态方法中调用实例方法,您只需要为调用指定一个显式实例对象。