java Java静态方法访问私有变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5129107/
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
Java static methods accessing private variables
提问by T.K.
I was under the impression that private non-static variables could only be accessed by methods called on the object that the variables reside in, but this is not the case. Could someone please explain the reasoning behind why the following compiles and runs?
我的印象是私有非静态变量只能通过在变量所在的对象上调用的方法访问,但事实并非如此。有人可以解释为什么以下编译和运行的原因吗?
public class Sandbox {
private String _privateString = "unmodified";
public static void setPrivateString(String str, Sandbox s) {
s._privateString = str;
}
public String toString()
{
return _privateString;
}
public static void main(String[] args) {
Sandbox s = new Sandbox();
setPrivateString("modified", s);
System.out.println(s);
}
}
Output:
输出:
modified
EDIT:The same is true in C#.
编辑:在 C# 中也是如此。
回答by davin
Private member variables of class A can be accessed (i.e. read/written to) by anymethod of class A (static or non-static), so in your example, since the method changing the string is a method of the same class the member belongs to, it is granted access to the variable.
类 A 的私有成员变量可以通过类 A 的任何方法(静态或非静态)访问(即读/写),因此在您的示例中,由于更改字符串的方法是同一类成员的方法属于,它被授予对变量的访问权限。
The reason is because a class is considered a self-contained body of logic (i.e. a specific implementation), so it makes sense that privacy is contained within a class; there is no reason to exclude static methods from that access right, since they are also part of the specific implementation the class provides.
原因是因为一个类被认为是一个自包含的逻辑体(即一个特定的实现),所以隐私包含在一个类中是有道理的;没有理由从该访问权限中排除静态方法,因为它们也是该类提供的特定实现的一部分。
回答by Feisty Mango
The rule is simple:
规则很简单:
member methods of a class can access and modify private members of the same class regardless of their visibility.
一个类的成员方法可以访问和修改同一个类的私有成员,而不管它们的可见性。
回答by v6ak
As mentioned in some other posts, Java's visibility system is class-based, not an object-based one.
正如在其他一些帖子中提到的,Java 的可见性系统是基于类的,而不是基于对象的。
Note that this is utilized in the compiler: When you have nested classes and you access a private field of the outer class, a public synthetic static method is generated to allow the access. It is usually named "access$0" etc. You can create a bytecode that violates encaplulation without the Reflection API by using these synthetic methods. You can also access them from the Reflection API without enabling access to private members. Many crazy things can be done...
请注意,这是在编译器中使用的:当您有嵌套类并访问外部类的私有字段时,会生成一个公共合成静态方法以允许访问。它通常被命名为“access$0”等。您可以使用这些合成方法创建一个违反封装的字节码,而无需使用反射 API。您还可以从 Reflection API 访问它们,而无需启用对私有成员的访问。可以做很多疯狂的事情......
If there was not such visibility system, compiler probably would need to compile it elsehow.
如果没有这样的可见性系统,编译器可能需要以其他方式编译它。
... Hoewver, the end-programmer usually don't need to know this detail. IDEs don't include synthetic methods in code completion and I hope that compilers (except Jasmin) don't allow you to use it. So if you don't generate bytecode and don't use Reflection API and you ignore these methods in the stacktrace, you probably don't need to know this detail.
...然而,最终程序员通常不需要知道这个细节。IDE 在代码完成中不包含合成方法,我希望编译器(Jasmin 除外)不允许您使用它。因此,如果您不生成字节码并且不使用反射 API 并且您忽略堆栈跟踪中的这些方法,您可能不需要知道这个细节。
回答by Costi Ciudatu
You seem to be confusing visibility
with scope
. The instance variables are in the scope of an instance, so they cannot be accessed in a static method directly, but only with an instance reference qualifier: s._privateString
in your case.
你似乎是混乱visibility
与scope
。实例变量在实例的范围内,因此不能直接在静态方法中访问它们,而只能使用实例引用限定符:s._privateString
在您的情况下。
However, this does not mean that instance variables are not visiblefor a static method inside the same class, as private
means visible inside the class (for any member with any scope).
然而,这并不意味着实例变量对于同一个类中的静态方法不可见,而是private
意味着在类中可见(对于具有任何作用域的任何成员)。
回答by CrazyCoder
Your code is compiled because inside setPrivateString(String str, Sandbox s)you are accessing the private variable _privateStringby reference variable s.
您的代码已编译,因为在setPrivateString(String str, Sandbox s)内部,您正在通过引用变量 s访问私有变量_privateString。
A non-static member can only access by instance variable from the static API.
非静态成员只能通过静态 API 中的实例变量进行访问。
Check this code
检查此代码
public class Sandbox {
public static void main(String[] args) {
Sandbox s = new Sandbox();
// testAccess();// If you uncomment this line you will get compile time error
s.testAccess();//can only access in this way
}
private void testAccess() {
System.out.println("can only access by instance variable from static method");
}
}