Hi I have two interface Ainterface and Binterface having same static final variable as 'i' which is declared as 10 and 20 respectively, I am implementing these two interfaces two my class InterfaceCheck where I am declaring same interface variable as static and final and initialized to 30. When I try to print the value of i in my class I am getting 30 as output. can some one explain me why I am able to reinitialize i to some other value even though its a final variable.
CODE
public interface Ainterface {
public final static int i=10;
}
public interface Binterface {
public static final int i=20;
}
public class InterfaceCheck implements Ainterface,Binterface {
public static final int i=30;
public static void main(String[] args) {
System.out.println(i);
}
}
>> output : 30
Class fields are always resolved on the static type of the reference.
In
public static void main(String[] args) {
System.out.println(i);
}
it implicitly does
System.out.println(InterfaceCheck.i);
so that is what you see.
Also, static fields are not inherited.
Static variables belong to the class itself (not to the instance) and these variables are not inherited by child class or implementing class.
Therefore:
public class InterfaceCheck implements Ainterface,Binterface {
public static final int i=30;
}
is not overriding i from those 2 interfaces. It is actually declaring a new independent static final variable.
Java has single inheritance because multiple inheritance has the problem of which members to pick when inherited classes collide on member names. But Java provides interfaces because that provides much of the power of multiple inheritance (additional behaviors) without the risk of name collision (but at the cost of choosing which methods so provide when method signature collision occurs).
Allowing class variables in interfaces is a relaxation of this rule, but was probably allowed because of where the member variable is located (one per class). As anubhava and Sotirios said they are not inherited, but declaring a new member, obscuring the inherited variable.
Your question concerns lexical scope. Since you have declared three 'public' variables which are class members, then you need to resolve scope. Since you have two inherited interfaces, do you really mean to define/set your own class variable, or to modify one or both of the inherited interface class variables?
I recommend you play around with the code to understand it fully whats going on, Very old thread here but all the same just wanted to add the following:
Comment out the static class "i" and when you run the code you will see java telling you "reference to i is ambiguous" ie, it does not know which one you want to call as it exists in both interfaces. Now un-comment the class static "i" and add two more printouts with the reference to both interfaces. As they are static this is allowed.
public static final int i=30;
public static void main(String[] args) {
System.out.println(i);
System.out.println(Ainterface.i);
System.out.println(Binterface.i);
}
30
10
20
Again if you remove the InterfaceCheck class static "i" constant and remove one of the interfaces it implements, say Binterface. You can reference the constant from Ainterface without its explicit reference as its the only static "i" created.
public class InterfaceCheck implements Ainterface {
public static void main(String[] args) {
System.out.println(i); //This will out Ainterface.i value of 10
//System.out.println(Ainterface.i);
//System.out.println(Binterface.i);
}
Related
This question already has answers here:
Anonymous-Inner classes showing incorrect modifier
(4 answers)
Closed 3 years ago.
To my understand correctly anonymous classes are always final:
This has been mentioned specifically in JLS 15.9.5
However, when i run the following code to check that it is showing that Inner class is not final.
public class Test{
static class A<T> {
}
public static void main(String arg[]) {
A<Integer> obj = new A() {
};
if ((obj.getClass().getModifiers() & Modifier.FINAL) != 0) {
System.out.println("It is a final " + obj.getClass().getModifiers());
} else {
System.out.println("It is not final " + obj.getClass().getModifiers());
}
}
}
Output of above program is :
It is not final 0
Please clear my doubt as i am not able to understand this behavior.
I agree this may be considered a bug, given that other cases in the JLS exhibit a different behavior. Case in point is an interface: As per section 9.1.1.1:
Every interface is implicitly abstract.
And when running the below:
interface X {
void foo();
}
public static void main(String arg[]) {
System.out.println(Modifier.isAbstract(X.class.getModifiers()));
}
It returns true.
Another example is an enum where the JLS specifies:
An enum declaration is implicitly final unless it contains at least one enum constant that has a class body
And the below example is perfectly aligned with it.
enum X {
}
public static void main(String arg[]) {
System.out.println(Modifier.isFinal(X.class.getModifiers())); // true
}
Explicit is something what is written in the source code. So, if something is declared as public final class, it means that the class is explicitly final.
Implicit is something that is not written down in the source code, but that in the context of a certain construct or based on the language rules, an element behaves as it were declared with the specified modifier.
For example, the keyword enum in the declaration enum SomeEnum { } causes SomeEnum to be final, because the language rules prescribe it. Its effect is the same as the effect of the keyword final.
The example of an anonymous class being implicitly final is because no language construct exists to override an anonymous class. So it behaves as if it were final. I think the word "effectively" is better here.
However, you cannot make assumptions based on how reflection presents things. Consider the following snippet:
public class Test {
interface SomeInterface { }
abstract interface SomeAbstractInterface { }
static abstract class SomeAbstractClass { }
enum SomeEnum { }
public static void main(String arg[]) {
System.out.println(Modifier.toString(SomeInterface.class.getModifiers()));
System.out.println(Modifier.toString(SomeAbstractInterface.class.getModifiers()));
System.out.println(Modifier.toString(SomeAbstractClass.class.getModifiers()));
System.out.println(Modifier.toString(SomeEnum.class.getModifiers()));
}
}
The result is this:
abstract static interface
abstract static interface
abstract static
static final
Both interface and abstract interface are considered an abstract interface. They are also considered static by reflection. Apparently, in the process of parsing and compiling the Java source code, some modifiers could be removed or added.
JLS 15.9.5 "...implicitly final"... But that is not "final", what is meant is that you just can't extend an anonymous class. There is no syntactic construction for this, but the class is not marked as final.
I have an abstract superclass called operation.java and several subclasses extending this class and representing operations. Each such subclass should contain an array of normalizing contants which should be static because it holds globally. I have the following example:
abstract class Operation {
private static double[] normalizingConstants;
protected Operation() {
normalizingConstants = new double[10];
}
}
class AddOp extends Operation {
protected AddOp() {
super();
}
}
class MinusOp extends Operation {
protected AddOp() {
super();
}
}
Does each subclass hold its own static normalizingConstants? If I call AddOp.normalizingConstants[0] and MinusOp.normalizingConstant[0] I want different results. How can this be achieved?
Does each subclass hold its own static normalizingConstants?
No, there is only one normalizingConstants (Operation.normalizingConstants). static fields are tied to the class where they are declared.
If I call AddOp.normalizingConstants[0] and MinusOp.normalizingConstant[0] I want different results. How can this be achieved?
If you need different normalizingConstants arrays, you need to declare another static variable in your sub classes, like
class MinusOp extends Operation {
private static double[] normalizingConstants;
...
Note that your normalizingConstants fields are only accessible from within the delaring classes since they are declared private.
Also, you should not initialize your static array in the constructor - use a static initializer instead. Otherwise, the array is re-initialized each time you create a new instance of your class (or any sub class).
I know that it's possible to do the following:
public class Indeed{
private class inner {
static final int try1 = 10;
}
}
Why? what's the point of allowing such a declaration?
Moreover it's still possible do the same thing in a local class:
public void doThing() {
class LocalClass {
static final int try1 = 10;
}
}
What's the use of a static final in those bits of code?
I am pretty sure I'll never use them, however I need to understand why they are used as I have an OCPJP7 exam to do.
Thanks in advance.
The purpose of a static variable is to be shared by all instances of the class. In both examples, you can have several instances of your private class / local class, so as specified they will share static variables among instances. What would be pointless is if you could only instantiate your class once.
JLS 8.1.3. : Inner Classes and Enclosing Instances
Inner classes may not declare static members, unless they are constant
variables (§4.12.4), or a compile-time error occurs.
The way I see it in the specs, is not having to answer the following dilemma:
static variables of an inner class are shared amongst all instances of the same outer class instance (but they can have different values from an outer class instance to another)
static variables of an inner class are shared amongst all existing instances in the VM, whatever their outer class instances.
Fortunately, when you declare it final, you know it will be the same for every instance, so you don't have to worry about this problem. That's why it is allowed.
For the question "why do static fields of inner classes have to be final":
This restriction is stated in the JLS as
Inner classes may not declare static members, unless they are constant
variables (§4.12.4), or a compile-time error occurs.
But this doesn't tell us why. Let's think about how we use inner classes. Imagine I write (try to) this.
public class A{
private class B{
static x;
}
public void updateX(int y){
B.x=y;
}
public void printX(){
System.out.println(x);
}
}
What happens when I do this
A one = new A();
A two = new A();
one.doStuff(1);
two.doStuff(2);
one.printX();
two.printX();
What should be printed? 1 then 2 or 2 twice? x is static so it should only exist in one place (in the Klass object of B) but as B is an inner class it should be specific to that instance of A. If we allowed static non final fields we would need to create an instance-specific Klass object per instance of the outer class. Which we don't want to have to do!
Static final fields are therefore allowed as they can live in the Klass object of B happily, and be shared across all instances of the outer class, because they can never change (being final).
public class A
{
public static int i;
}
public class B extends A
{
public static void main(String[] args)
{
System.out.println("print i=" + B.i); // referred to A.i
}
}
My question here is how B.i is referred to the A.i?
If the static variable i is inherited why java allows to define another variable i in B class also?
A public or protected member of A is visible in all subclasses of A.
If the static variable i is inherited why java allows to define another variable i in B class also?
It's hard to speculate as to why. One possible reason is that this allows one to add members to a base class without breaking any derived classes that already happen to have a member with the same name.
Note that, if you define another i in B, it will shadow A.i, making it difficult to access the latter. I've seen people expecting this to behave polymorphically, but it doesn't (your case is slightly different anyway, since A.i is static).
i here is a static variable.A static variable,in layman terms,means a single copy being accessed by all classes.So,since your class B extends A,B has an access to the static variable of A.
If you define the variable locally,then the local value of the variable hides the parent class value.
there are 2 different things, scope and visibility. you can not redefine a variable in same scope twice (though you can redefine them in nested scopes).
But in case of inheritance, the subclass is out of scope of superclass, but yet has the visibility to that variable because of inheritance. So sub class allows you to define variable i again, though it will hide super class's variable. you wont be able to see its value. (unless used any getter from superclass)
Java allows you to change the specific variable value for the extended class.
This is because, static variables are shared between all objects of the same class.
It is a variable which belongs to the class and not to object(instance).
So, when extending the static variables of the parent class are not actually part of the extended class BUT are accessible (as long as they were not private).
Additionally, this can be used to do things such as:
using different STATIC CONSTANT for extended classes.
A use for this is to identify classes based on a STATIC integer as apposed to utilizing instanceof. This can be further combined with a switch to change behavior based on an objects type.
So, in the most basic example imagine we want to create a variable represent TYPE.
class A
{
public static final int NODE_TYPE = NODE_PERSON;
public static final int NODE_PERSON = 0;
public static final int NODE_CAR = 1;
}
class B extends Class A
{
public static int NODE_TYPE = NODE_CAR;
}
This has been used in many frameworks including Eclipse Abstract Syntax Trees:
http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.jdt.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fjdt%2Fcore%2Fdom%2FASTNode.html
You will see a list of STATIC INTEGERS which represent different Node Types.
I have a Java problem with nested classes.
My first class structure looked like this:
public class TopClass {
public void mainMethod() {
// uses the different "method" methods from
// NestedClass-implementing nested classes
}
private interface NestedClass {
public void method();
}
private class NestedClass1 {
public void method() {
}
}
private class NestedClass2 {
public void method(){
}
}
}
But now I want these method() methods to be static because they should be principally.
I cannot make them static without having them in a static class, but that's no problem, I made the classes static, they should be anyway.
It looks like this right now:
public class TopClass {
public void mainMethod() {
// uses the different "method" methods from
// NestedClass-implementing nested classes
}
private static interface NestedClass {
public void method();
}
private static class NestedClass1 {
public static void method() {
}
}
private static class NestedClass2 {
public static void method(){
}
}
}
But then the trouble begins. A static method does not inherit correctly from a non-static interface method, as I get this message This static method cannot hide the instance method from TopClass.NestedClass in Eclipse.
When I make the interface method static, it gives me this error: Illegal modifier for the interface method method; only public & abstract are permitted
So I thought of an abstract class, and tried this:
public class TopClass {
public void mainMethod() {
// uses the different "method" methods from
// NestedClass-implementing nested classes
}
private static abstract class NestedClass {
public static abstract void method();
}
private static class NestedClass1 {
public static void method() {
}
}
private static class NestedClass2 {
public static void method(){
}
}
}
But again, seemingly abstract methods cannot be declared static: The abstract method method in type NestedClass can only set a visibility modifier, one of public or protected.
Leaving the static away (in the abstract class method), errors this on the method methods in the NestedClass1 & 2: This static method cannot hide the instance method from TopClass.NestedClass.
Isn't there any way to declare some kind of superstructure for covering static methods?
EDIT:
The problem I actually try to solve it the lack of possibility of Java for storing references to methods. So instead I have those classes everyone with just one method, but to store them in a List f.e. they must be able to be "caught" by a superstructure.
I got the hint to try anonymous classes or enums, gonna try that now.
Interfaces and statics don't go together. At all. There is no Java support for creating / imposing patterns on static methods.
A static method declaration must always be followed by a definition. It cannot be implemented by subclasses.
I think you're just not approaching your problem right. Try a different approach!
Make NestedClass an interface NestedInterface and store your different implementations as anonymous classes implementing this interface:
public static final NestedInterface firstNested = new NestedInterface() {
#Override
public void method() {
// ...
}
};
Make NestedClass an enumeration NestedEnum and store your different implementations as enumeration values implementing an abstract method from the enumeration. This only works if you have a fixed number of implementations you which to choose from and you do not want to accept NestedClass implementations from outside sources.
public enum NestedEnum {
FIRST {
#Override
public void method() {
// ...
}
};
public abstract void method();
}
EDIT: In reply to your comment:
The classes itself are static as well..
static in the context of a nested class means that this class can be instantiated without an instance of the containing class.
A regular nested class such as in your first example can be instantiated through TopClass.this.new NestedClass1(). Normally you'd simply write new NestedClass1() from within the constructor or an instance method of TopClass, but in this verbose form you can clearly see the dependence on TopClass.this. This can also be seen from any method of NestedClass1, as you have access to the containing class with TopClass.this.
A static nested class such as in your second example can be instantiated through new TopClass.NestedClass1(). Once again, you could just write new NestedClass1() but the verbose form clearly shows that the construction only depends on TopClass and is not associated with an instance of TopClass. You could even create an instance from an outside class using the same snippet new TopClass.NestedClass1() without ever creating a TopClass instance.
I suggest you take a look at this question on inner classes and static nested classes.
The fact the your interface/abstract class is nested is irrelevant to the problem.
You just can't. There is no way in Java to enforce some class to implement static methods. Just cry and surrender and use instance methods.
static abstract is a contradiction. Static methods are not like other languages' class methods. When you make a static method it goes on a single class, it doesn't get inherited by or have its implementation deferred to subclasses.
You don't explain why you want these methods to be static. If you want these methods to be defined by subclasses then they shouldn't be.