The main method tries to access var, but results in ambiguous call. Why? Instance variable var in Base1 isn't accessible (visible?) from static context anyway.
class Base1 {
int var;
}
interface Base2 {
public static final int var = 0;
}
class Test extends Base1 implements Base2 {
public static void main(String args[]) {
System.out.println("var:" + var);
}
}
The JLS rule for field access ambiguity is
If the identifier names several accessible (ยง6.6) member fields in
type T, then the field access is ambiguous and a compile-time error
occurs.
And on the subject of accessibility
A member (class, interface, field, or method) of a reference type, or
a constructor of a class type, is accessible only if the type is
accessible and the member or constructor is declared to permit access:
It doesn't make a distinction about whether the instance field access would cause a compile error in a static context.
Note that you could have had
public static void main(String args[]) {
Test test = new Test();
System.out.println("var:" + test.var);
}
You'd still have the ambiguity.
To make it unambiguous put the interface name as qualifying prefix:
class Test extends Base1 implements Base2 {
public static void main(String args[]) {
System.out.println("var:" + Base2.var);
}
}
Inititally at step one compiler will look for variable var in the class which you extend and the interface you implement. Since it finds a variable at both places in step two, it shows ambiguity.
The static and non static contexts do not rule on how variables are permitted to be accessed
The access modifiers are the ones which actually rule this...
change the access modifier for var in the Base1 to private and the ambiguity disappears, though this might not be the way you want it to shape up but access modfiers actually dictate the reference to instance variables rather than the static no static contexts.
class Base1 {
private int var;
//static int var=5;
}
interface Base2 {
public static final int var = 0;
}
class ambiguousNonStaticCall extends Base1 implements Base2 {
public static void main(String args[]) {
System.out.println("var:" + var);
}
}
The above code compiles fine.
Related
I've read this, and also this and I guess I'm getting the theroical point af static and non static content but I'm unable to apply it to the following case (which is supposed to work) May be so, so, so basic but... humans.
public class MyClass {
private String varA ;
private int varB;
public MyClass(String var, int var) throws SocketException {
//stuff to work with
}
private void methodA() {
//more stuff....
}
public static void main(String args[]) throws IOException {
//How to instatiate MyClass(varA,varC)?
}
}
So, how it's supposed to be instatiated MyClass from main if MyClass is not static?
How to instatiate MyClass(varA,varC) ?
public static void main(String args[]) throws IOException {
//local variables
String varA = "A";
int varC = 10;
//Use the constructor of the class to create an object
MyClass myClassObj = new MyClass(varA, varC);
}
You always need to use the constructors provided by the class to instantiate a class. You don't have the default (no argument) constructor in your class, so you need to pass the constructor arguments as shown above to instantiate the class.
You can look here.
In your MyClass class instance variables varA, varB are created/maintained for each object(instance) separately.
Just to add, if there are any static variables present in a class, they will be maintained only per class (not for each object).
I hope this answer will be helpful for you to understand why main method is static in non-static class
Why is the Java main method static?
Also, in code :
MyClass myClass = new MyClass(varA, varC);
Create new instance of you class using public constructor with your own parameters list.
Agree with JavaGuy.
Just for your clarity's sake, main method is made static so that it can be called from JVM without instantiation of the class. Hence to access any non static member of the class you need to have an instance of the class as mentioned by above solution by JavaGuy.
I have got the following line from Oracle Java tutorial
You can find this here Execution under the heading "12.4. Initialization of Classes and Interfaces"
Initialization of a class consists of executing its static initializers and the initializers for static fields (class variables) declared in the class.
It will be great if someone explain me How "initializers for static fields" is referring to "class variables".
A "class variable" is a variable that is declared as a static property of a class. By "initializers for static fields" they are referring to the initialization of these static variables, which happens when the class is loaded. Here's an example:
public class MyClass {
private static int num = 0; //This is a class variable being initialized when it is declared
}
Another way to initialize static fields is to use static blocks:
public class MyClass {
private static int num;
static {
num = 0; //This a class variable being initialized in a static block
}
}
These static blocks are run from top to bottom when the class is loaded.
In the end, the quote is trying to say that "class variable" is just another name for "static field."
A static member is a variable that belongs to the class as a whole, not a specific instance. It's initialized once, when the classloader loads the class.
E.g.:
public class MyClass {
// Note the static modifier here!
private static int someVariable = 7;
}
One common usecase for such variables is static final members of immutable types or primitives used to represent constants:
public class Human {
public static final String SPECIES = "Homo sapiens";
public static final int LEGAL_DRINKING_AGE = 21; // U.S centric code :-(
}
For example I've got simple class
class Simple {
private int i = 6;
private static void method(Simple obj) {
System.out.println("Value i: " + obj.i);
}
public void method() {
method(this);
}
public static void main(String[] args) {
new Simple().method();
}
}
Why I can get access to i in static method?
private members can be accessible with in the class. Your static method belongs to the same class. Hence you can access.
Modifier Class Package Subclass World
---------------------------------------------
private **Y** N N N
Update: To avoid the confusion, move the static method to other class and try once.
Don't get confused with static and private/public/[default]. Those are two separate things. A static function can access private non-static field because it is part of the class. And thats whats private does, only restricting access to the class level, without any distinction being made between static or not.
If it's the staticness that's bothering you, obj is a proper "not static" object, which us why it has an accessible non-static field. The method being static is irrelevant.
you are accessing instance of object not directly class variable. when you use direly "i" without reference to object its not allowed.
Private variable visibility is by default in with in class access .
public class Simple {
private int i = 6;
private static void method(Simple obj) {
System.out.println("Value i: " + i); //compile Error ::Cannot make a static reference to the non-static field i
}
public void method() {
method(this);
}
public static void main(String[] args) {
new Simple().method();
}
}
In the class 'Tosee' below, hiddenInt is visible when I call s.hiddenInt.
However, when I create a "ToSee" object in another class, 'CantSee', the private variable isn't visible. Why is this so? I was under the impression that private means that in any instance of a class, the client cant see that particular instance variable or method? Why then am I able to see hiddenInt in the main method of 'ToSee'?
public class ToSee {
private int hiddenInt = 5;
public static void main(String[] args) {
ToSee s = new ToSee();
System.out.println(s.hiddenInt);
}
}
public class CantSee {
public static void main(String[] args) {
ToSee s = new ToSee();
System.out.println(s.hiddenInt);
}
}
Private in Java means the variable or method is only accessible within the class where it is declared. If your impression about private was true, it will not be accessible anywhere ever which makes it completely useless.
A main method has special connotations in Java, yet it's still a method belonging to a particular class.
Private fields in the enclosing class are accessible to the main method, either through a local instance (in the case of instance fields) or directly (in the case of static fields).
The modifier private makes a variable or method private to the type (class) it is declared in. So only this class can see it.
You can see the variable hiddenInt in ToSee.main because ToSee.main is a static method of the TooSee class. Thus it can access all private variables of a ToSee, either static or instance variables.
Private does also NOT mean private to an instance. An instance of one class can access the private variables of another instance of the same class.
public class ToSee {
private int hiddenInt = 5;
public void printInt(ToSee toSee){
System.out.println(toSee.hiddenInt);
}
public static void main(String[] args) {
ToSee tooSee1 = new ToSee();
ToSee tooSee2 = new ToSee();
tooSee2.hiddenInt = 10;
tooSee1.printInt(tooSee2); // will output 10
}
}
I was under the impression that private means that in any instance of a class,
the client cant see that particular instance variable or method?
Incorrect! Private access modifier simply means that the variable on which it is used will be accessible only in the enclosing class. Period. Since your main() method is in ToSee class which is where you have the hiddenInt private instance variable, it is visible. Where as in case of CantSee class which is not in the ToSee class it is not visible(you need to use getter/setter methods.)
private means invisible to any code outside of the outermost enclosing class it is present in. Since the CantSee class is separate from the ToSee class it cannot see the private field. If CantSee and ToSee were both members of the same class, or one was a member of the other, then you would be able to read the private field. A few examples of structures in which the private field is readable follow :
public class Outer {
public class ToSee {
...
}
public class CantSee {
...
}
}
or
public class CantSee {
...
public class ToSee {
...
}
}
Why can we have static final members but cant have static method in an non static inner class ?
Can we access static final member variables of inner class outside the outer class without instantiating inner class ?
YOU CAN have static method in a static "inner" class.
public class Outer {
static String world() {
return "world!";
}
static class Inner {
static String helloWorld() {
return "Hello " + Outer.world();
}
}
public static void main(String args[]) {
System.out.println(Outer.Inner.helloWorld());
// prints "Hello world!"
}
}
To be precise, however, Inner is called a nested class according to JLS terminology (8.1.3):
Inner classes may inherit static members that are not compile-time constants even though they may not declare them. Nested classes that are not inner classes may declare static members freely, in accordance with the usual rules of the Java programming language.
Also, it's NOT exactly true that an inner class can have static final members; to be more precise, they also have to be compile-time constants. The following example illustrates the difference:
public class InnerStaticFinal {
class InnerWithConstant {
static final int n = 0;
// OKAY! Compile-time constant!
}
class InnerWithNotConstant {
static final Integer n = 0;
// DOESN'T COMPILE! Not a constant!
}
}
The reason why compile-time constants are allowed in this context is obvious: they are inlined at compile time.