This question already has answers here:
Why can I access a private variable from main method?
(7 answers)
Closed 8 years ago.
I recently see a question that what is the execution result of this code below.
public class Sandys {
private int court;
public static void main(String argv[]){
Sandys s = new Sandys(99);
System.out.println(s.court);
}
Sandys(int ballcount){
court = ballcount;
}
}
I think it can't be executed because in main i try to access a private variable.
However, this code can be perfectly executed, and the result is 99. So I am confused, why the private variable can be accessed in this code? Though the main is in Sandys class, however i create a new Sandys. Can I still access the private variable of the new Sandys object in main?
You can access private members from inside the same class, even in static methods.
main() is a special method because it is used as a starting point for java application. However, it is still a normal static method and it follows all access restrictions of static methods. Is this main() a class method? Yes, it is. Hence, it can access private members of the same class.
Consider this: if there was no access to private fields factory methods would have to be written differently.
class A {
private int a=0;
private int b=0;
private A() {}
//getters
public static A getNewInstance(int a, int b) {
A a = new A();
a.a = a;
a.b = b;
return A;
}
It does make sense, doesn't it?
You can access ALL private, protected, public and not modifier variables inside class, but you can not access private variable from another class.
P.S. It is truth also for C#, C++ and many other programming languages.
A class is defined to some particular job and in that way it may use some variables that it don't want others to access it("others" means outsider classes) and some you want other classes to access it.It all depends on your requirement.
"Private instance variables are defined to be used in only with in the class".and since in your code you are trying to access the private instance variable inside the class itself then it is perfectly legal.
Note: A static method cannot access the instance variables if u want specify the instance i mean create the instance(object) inside of the static method and access it through the created reference.
Related
This question already has answers here:
System.out is declared as static final and initialized with null? [duplicate]
(2 answers)
Closed 5 years ago.
As to access the methods of PrintStram class an object must be created, so how the out variable is able to access those methods when it is assigned null.
public final static PrintStream out = null;
This is the declaration in System class.
I tried to write the similar code but then it gives NullPointerException. My code is given below.
class First{
public void display(){
System.out.println("Hello");
}
}
class Second{
public final static First s1=null;
}
public class Third{
public static void main(String[] args) {
Second.s1.display();
}
}
To make this code run i will have to make either display method static or define s1 as-
public final static First s1=new First();
The field isn't null at runtime. It's assigned the relevant stream stdout or something else if it has been redirected. The mechanism is internal to the JVM, so the code isn't readily visible in the JDK sources. You can use System.setOut() to modify the field, which again uses internal mechanisms as the field is final and normally wouldn't be assignable.
You may have missed the System.initializeSystemClass() which according to the documentation is called after the class initialization. It initialize the in, out and err stream. It use native methods to do that, so it doesn't have to respect the final modifiers.
This question already has answers here:
Cannot refer to a non-final variable inside an inner class defined in a different method
(20 answers)
Why are only final variables accessible in anonymous class?
(15 answers)
Closed 9 years ago.
Given the following inner class (IsSomething) within a method:
public class InnerMethod {
private int x;
public class Something {
private int y;
public void printMyNumber(double x)
{
class IsSomething extends Something {
public void print() {
System.out.println(x);
}
}
}
}
}
Why does the X variable has to be FINAL to make it work..?
(I'm talking ofc about the X parameter of the "printMyNumber" function.)
The difference is between local variables vs class member variables. A member variable exists during the lifetime of the enclosing object, so it can be referenced by the inner class instance. A local variable, however, exists only during the method invocation, and is handled differently by the compiler, in that an implicit copy of it is generated as the member of the inner class. Without declaring the local variable final, one could change it, leading to subtle errors due to the inner class still referring to the original value of that variable.
Final local variables
There are two reasons I know for making a local variable or a
parameter final. The first reason is that you don't want your code
changing the local variable or parameter. It is considered by many to
be bad style to change a parameter inside a method as it makes the
code unclear. As a habit, some programmers make all their parameters
"final" to prevent themselves from changing them. I don't do that,
since I find it makes my method signature a bit ugly.
The second reason comes in when we want to access a local variable or
parameter from within an inner class. This is the actual reason, as
far as I know, that final local variables and parameters were
introduced into the Java language in JDK 1.1.
public class Access1 {
public void f() {
final int i = 3;
Runnable runnable = new Runnable() {
public void run() {
System.out.println(i);
}
};
}
}
Inside the run() method we can only access i if we make it final in the outer class. To understand the reasoning, we have to
look at what the compiler does. It produces two files, Access1.class
and Access1$1.class. When we decompile them with JAD, we get:
public class Access1 {
public Access1() {}
public void f() {
Access1$1 access1$1 = new Access1$1(this);
}
}
and
class Access1$1 implements Runnable {
Access1$1(Access1 access1) {
this$0 = access1;
}
public void run() {
System.out.println(3);
}
private final Access1 this$0;
}
Since the value of i is final, the compiler can "inline" it into the inner
class. It perturbed me that the local variables had to be final to be
accessed by the inner class until I saw the above.
When the value of the local variable can change for different
instances of the inner class, the compiler adds it as a data member of
the inner class and lets it be initialised in the constructor. The
underlying reason behind this is that Java does not have pointers, the
way that C has.
Consider the following class:
public class Access2 {
public void f() {
for (int i=0; i<10; i++) {
final int value = i;
Runnable runnable = new Runnable() {
public void run() {
System.out.println(value);
}
};
}
}
}
The problem here is that we have to make a new local data member each time we go through the for loop, so a thought I had today
while coding, was to change the above code to the following:
public class Access3 {
public void f() {
Runnable[] runners = new Runnable[10];
for (final int[] i={0}; i[0]<runners.length; i[0]++) {
runners[i[0]] = new Runnable() {
private int counter = i[0];
public void run() {
System.out.println(counter);
}
};
}
for (int i=0; i<runners.length; i++)
runners[i].run();
}
public static void main(String[] args) {
new Access3().f();
}
}
We now don't have to declare an additional final local variable. In fact, is it not perhaps true that
int[] i is like a common C pointer to an int? It took me 4 years to
see this, but I'd like to hear from you if you have heard this idea
somewhere else.
The methods in an anonymous class don't really have access to local variables and method parameters. Rather, when an object of the anonymous class is instantiated, copies of the final local variables and method parameters referred to by the object's methods are stored as instance variables in the object. The methods in the object of the anonymous class really access those hidden instance variables.
From the JLS :
Any local variable, formal method parameter or exception handler parameter used but not declared in an inner class must be declared final. Any local variable, used but not declared in an inner class must be definitely assigned (ยง16) before the body of the inner class.
This is because the lifetime of an instance of a local class can be much longer than the execution of the method in which the class is defined. For this reason, a local class must have a private internal copy of all local variables it uses (these copies are automatically generated by the compiler). The only way to ensure that the local variable and the private copy are always the same is to insist that the local variable is final.
I'm learning Java and I just wonder why public and private is used when a method or members is static? When static is used they are class methods and class members and could be used from other classes without creating an object, so is public and private necessary? Some help is preciated to understand. Sorry if this question is too simple for some.
The accessibility of a field or method is orthogonal to the fact that it's static or not.
You could have a static method accessible from the outside, and a static method that must only be used from inside the class itself (by other static or non-static methods). The same goes for fields.
For example:
// not visible from the outside
private static final long MILLISECONDS_IN_A_MINUTE = 1000L * 60 * 60;
public static Date addMinutes(Date d, int amount) {
return addMillis(d, MILLISECONDS_IN_A_MINUTE * amount);
}
// not visible from the outside
private static Date addMillis(Date d, long amount) {
return new Date(d.getTime() + amount);
}
It's not necessary, but there can be static methods and data members for internal use only.
An example for this is if you want an unique id for every instance of the class:
class Foo
{
private static int nextId = 0;
private static int generateId() { return ++nextId; }
private int id;
public Foo()
{
id = generateId();
}
}
As you can see, nextId and generateId() are not needed outside the class, nor should they be used outside the class. The class itself is responsible for generating id's. But you need them to be static (well, you need nextId to be static, but you can also make generateId() static since it doesn't access non-static members).
Whenever an object Foo is created, the static counter is incremented, thus you get different ids for each instance of the class. (this example is not thread-safe)
Suppose you have a static public method and this method must access to a private attribute. This private attribute must be static too. There's one reason why private static exists.
Example :
public class Test {
private static int myattr = 0;
public static void foo() {
myattr = 2;
}
}
Above, myattr must be a static attribute in order to use it in the foo() method.
Yes it is needed.
If you have a Static Method and want to use a private variables in that method, then you need to declare it static too.
Or you want the static variables not be visible to other packages, then don't declare it public.
From what I remember, it's not really needed. But public means, basically in any programming language, that it can be used by outside files. With private it can only be used within that file, and static means you cannot change the value of said reference. Whether these be functions, or variables, the same rules apply. I might be off. Haven't done Java in about a year and a half.
The ways you can incorporate these types is up to you. After all, a program is only as diverse as it's user. ^_^
Public and private keywoards have to do with visibility: which members do you want to accessible to other classes and which should be hidden or encapsulated.
Static members relate to the class as a whole, while non-static members operate on object instances.
I'm learning Java and I just wonder why public and private is used when a method or members is static?
I believe your question is due to a common misconception that the access modifiers are for instances, but they're not!
Two different instances can access each others private members if they are of the same class.
In other words, the access modifiers works on class level. Since also static members belong to some class, it makes sense to have access modifiers also on them.
A static method (or variable) that should only be used by code in the same class (as in the example by JB Nizet) should be private, while a static method or variable that may be used by code in any class should be public.
When the static is used with methods it doesn't only mean that it should be used by the members of other classes.
The case when we access the static methods of a class is one when
the class (which contains the method) cannot be instantiated i.e. no objects can be created of that class.
There may be situations when two different classes may have static methods with same name. In that case you want to use the method of the same class not the method of other class.
let's assume we have the following code:
public class TestScope {
private int a = 1;
public static void main(String[] args) {
TestScope ts = new TestScope();
ts.a = 6;
System.out.println(ts.a);
}
}
Why at line: ts.a = 6; I can get access to private variable a?
I thought that private memebers cannot be accessed outside. I don't underestend this example.
Static methods are still considered part of the class they're declared in, and thus have access to private methods/fields.
If you had the main method (or any other static or instance method) in another class, you would indeed not be able to access a.
It's because a and main(String[]) are both part of the definition of the class TestScope
Private means that a variable or method can only be accessed inside the class definition. The fact that a is an instance variable doesn't mean it can't be accessed by a static public method in the same class.
If the public static void main(String[]) was inside a different class, then it would not be able to access ts's a, because a is hidden from other classes.
A static method is considered 'part' of the class it's in and so has private-scope access to instances of it. This same question was tackled here a couple days ago.
I heard that static methods should use only static variables in java.
But, main method is also static, right?
Your question: is the statement " static methods should use only static variables" correct?
No. The statement is not correct.
The correct statement will be "static methods can only use those instance variables that are defined static"
Take a look at following code and read the comments:
Class A{
int i;
static int j;
public static void methodA(){
i = 5; //cannot use since i is not static
j = 2; //can use.
int k = 3; //k is local variable and can be used no problem
**EDIT:**//if you want to access i
A a = new A();
//A.i = 5; //can use.
a.i = 5; // it should be non-capital "a" right?
}
}
First of all, a technicality: it's NOT true that "main method is also static". You can define a non-static main method, with whatever signature you choose; it just won't be a valid Java application entry point.
With regards to "static methods should use only static variables", this is also NOT true. The key concept here is that static methods and fields are class-specific, not instance-specific. You simply can't access an instance variable/method if you don't actually have an instance of that class; it's a compilation error.
So to be precise, without an instance, you can't access instance fields/methods. You can access static fields/methods without an instance. If you need to access instance fields/methods from a static method, you have to get an instance of that class one way or another, either by simply instantiating it, or by getting a reference to it from a static field or method parameter.
Let's take a look at this simple example:
public static void main(String args[]) {
System.out.println(args.length);
}
length is NOT a static field; it's an instance field of array instances, which args is. The static method main is able to get this instance (and thus access its instance methods and fields) because it's passed in as an argument.
Also, println is NOT a static method; it's an instance method of PrintStream instances. The static method main is able to get this instance by accessing the static field out of the class System.
To summarize:
A Java application entry point is a method that:
is named main
is public and static
returns void and takes a String[] argument as parameter
A method named main doesn't have to be a Java application entry point
(but it's best to reserve this name for that purpose)
Furthermore,
Instance fields/methods can only be accessed through an instance
Static fields/methods can be accessed without an instance
Static methods can get an instance of a class by one of the following ways:
creating a new instance
having it passed as an argument
accessing it through a static field of a class
accepting it as the return value of a static method of a class
catching it as a thrown Throwable
Maybe this piece of code will enlighten you:
public class Main {
private String instanceField = "Joe";
private void instanceMethod() {
System.out.println("Instance name=" + instanceField);
}
public static void main(String[] args) {
// cannot change instance field without an instance
instanceField = "Indy"; // compilation error
// cannot call an instance method without an instance
instanceMethod(); // compilation error
// create an instance
Main instance = new Main();
// change instance field
instance.instanceField = "Sydney";
// call instance method
instance.instanceMethod();
}
}
So you cannot access instance members without an instance. Within the context of a static method you don't have a reference to an instance unless you receive or create one.
Hope this helps.
To access non-static fields (instance variables) you need to have an instance.
Inside a non-static method, this is used as default instance:
class AnyClass {
private String nonStaticField = "Non static";
void nonStaticMethod() {
this.nonStaticField = "a text"; // accessing field of this
nonStaticField = "a text"; // same as before
}
}
Inside a static method there is no this to use as default instance, but you can1 still access instance variables if you provide the instance:
class AnyClass {
private String nonStaticField = "Non static";
static void staticMethod() {
AnyClass example = new AnyClass();
example.nonStaticField = "new value for non-static field";
}
}
1 - the field must also be accessible by Java's access control (declared public or in the same class ...)
A static method is called on a class instance and not to an object of a class. This means, that a static method is not able to access instance variables, because they are only instantiated in an object.
If you want to access an instance variable with a static method, you have to declare that variable as static.
public class Test {
private static int value = 0;
public static void main(String[] args) {
value++;
}
}
But to be honest, it's not the best idea to write everything in static methods. It's better to use the main method to instantiate new objects.
One important thing is that unless u create an instance of an class the instance variables don't exist practically it means JVM doesn't that there os an variable like int i unless u create an instance for that class. so, using an instance variable in a static method is an compilation error.
class A{
int i;
static int j;
static int b(){
i=10; // cannot be found
A a= new A();
a.i=10;//can be found in a's instance
}
}
But, we can use instance variables in instance methods because, instance methods are only called when object created so there is no problem in using instance variables inside it.
Hope ur clear about these things!
Yes static method cannot call non-static methods or variables of the class directly.
EDIT : One can create any local variables.
The static method can't access non-static variables outsides because you can use static method without class initialization, but it doesn't work for non-static outside variable. But you can define and use non-static variable in the static method.