Favoring static class usage over variable with same name - java

Class B extends Class A, Class A has a variable named K, I have a static Class named "K" also. Is there a way inside class B to favor using the static class K over the inherited variable K?
(I am working with decompiled code that was obfuscated, I cannot rename either of the versions of K)

You may need to refer to the class K with its full name, ie myPackage.K

Since K is in the default package, I think your only options will be to refer to class K using reflection or else write a class to wrap K so you can use a different name. Or if you're after some static members of K, you could use static imports to get at them, too.

Does this work?
class A {
int X;
}
class B extends A {
static class X {}
void foo() {
X = 5; // A.X variable
B.X x = new B.X(); // B.X nested class
}
}

Related

Some trouble with inner class visibility

I'm facing java inner class and I'm having some trouble with outer variables visibility.
class A {
private int x = 5;
class B extends A{
public void fun(B b){
b.x = 10; //here
}
}
}
Why I can't do something like this (see the "here" tag) if there are no visibility restrictions between inner and outer class? I'm really not understanding these rules.
In your example the member variable x is not a property of class B so b.x = 10 makes no sesne, hence the error, it's nothing to do with visibility rules. Trying x = 10 works fine, which is a short-cut for A.this.x = 10 or super.x = 10.
Modifier private cannot be accessed in sub classes.
class A {
private int x = 5; // The issue is in `private` in this line
class B extends A{
public void fun(B b){
b.x = 10; //here
}
}
}
If you remove the modifier private and change it to default, public OR protected, you will be able to access the variable.
Please go through the link for better understanding.
UPDATE:
Remove extends keyword (Now Class B will not be a sub class but only an inner class), and the variable x will only be accessed using this OR super keyword. The usage is elaborated at link
you need know this three private,protected,default,publicaccess specifiers
private variables only can be modified in the itself class.not include subclass
default variables can be modified in same package.
protected variables can be modified in subclass and in same package and itself
public variables can be modified any where.
you can saw this on this link
beside.if you use this example ,this can modified your variables with usingsuperspecifiers to access your visiable
class A {
private int x = 5;
class B extends A{
public void fun(B b){
b.x = 10; //here error
super.x=1;//this is ok
}
}
}
this b.x = 10; //here error this problem is b is a parm of a methods not a member-variable or a super class variable.
This one is quite special. Inner class can access the private field of the outerclass. This can be shown with the fun(A) method
class A {
private int x = 5;
class B extends A{
public void fun(A a){
a.x = 5; //Valid since we are in the same class (inner-class can access private field)
}
}
Now, if you have a B parameter, this is a bit different because it will try to use the inheritence instead of the outer-inner link :
public void fun(B b){
b.x = 10; //Access using inheritence, not OK for private field
((A)b).x = 10; //Casting into A to be able to access the private field (just like fun(A).
}
Note that this is a problem because you update a reference receive in parameter, you can update the current inner instance easily
public void fun(){
x = 10; //OK : access to A.x from inner class
super.x = 10; //OK : same
this.x = 10; // KO : trying to access a private variable from B scope
}

Polymorphic behavior in java

I have following java code,
interface A {
int a = 5;
}
class B {
int a = 6;
}
public class C extends B implements A {
int b = super.a;//Line 10
public static void main(String[] a) {
System.out.println(new C().b);//6
}
}
I was expecting compiler error at line 10 because compiler will not know which "a" to refer. But there was no compiler error. Output is 6. Can someone explain how it takes class B 's instance variable value(6) why not interface A's "a" value which is 5?.
super keyword is used to refer to the parent class which in this case is B. Hence you get output as 6.
a defined in interface A is static and a defined in Class B is an instance variable. Hence when we do super.a, it refers to the instance value of a which is defined in the Class B
If you rename the variable in B say as aa, you will get compiler error saying a cannot be resolved or is not a field because a defined in interface A is not directly accessible in class C, because it is by default static. To access a defined in interface A, we need to make an explicit call to A.a in class C
If you define, a as static in class B, and remove super, you will get compiler error: The field a is ambiguous

re-inheritance static field from class and interface

interface A {
public static String name = "A";
}
interface B {
public static String name = "B";
}
class X implements A { }
class Y extends X implements B { }
public void test_getField() {
try {
assertEquals(B.class.getField("name"), Y.class.getField("name"));
} catch (NoSuchFieldException e) {
fail("Got exception");
}
}
Why does Y.class.getField("name") return B.name instead of A.name?
Is there any answer in the Java specification?
The direct superinterface will be searched before superclass, see the doc of getField:
The field to be reflected is determined by the algorithm that follows.
Let C be the class represented by this object:
If C declares a public field with the name specified, that is the
field to be reflected.
If no field was found in step 1 above, this
algorithm is applied recursively to each direct superinterface of C.
The direct superinterfaces are searched in the order they were
declared.
If no field was found in steps 1 and 2 above, and C has a
superclass S, then this algorithm is invoked recursively upon S. If C
has no superclass, then a NoSuchFieldException is thrown.
The key point here is that you're using reflection and getting unexpected behavior.
Although you already have the reflection algorithm, I will add a visual example.
First of all, using normal access you will get:
class Y extends X implements B {
public void test() {
System.out.println(name);
}
}
Error:(29, 36) java: reference to name is ambiguous both variable
name in com.test.A and variable name in com.test.B match
Now considering an example:
class Y extends X implements A, B {}
public class Main {
public static void main(String[] args) throws NoSuchFieldException {
Y y = new Y();
System.out.println("Y : " + y.getClass().getField("name"));
}
}
The output will be:
Y : public static final java.lang.String A.name
Changing signature to
class Y extends X implements A, B {}
Gives us output:
Y : public static final java.lang.String B.name
The direct superinterfaces are searched in the order they were
declared.
Further observation shows that actually we can get both names like:
class Y extends X implements A, B { }
public class Main {
public static void main(String[] args) throws IllegalAccessException {
Y y = new Y();
Field[] fields = Y.class.getFields();
for (Field field : fields) {
System.out.println(field.get(y));
}
}
}
Output:
A
B
And for both class Y extends X implements B { } and class Y extends X implements B, A { }:
B
A
The first name resolved in runtime comes from first implemented interface (direct superinterface) because it has higher precedence, then comes the value from the second interface, then the value from the superclass.
When you calling Y.class.getField("name") you're getting the first resolved name which comes from first direct superinterface - A.
This is an interesting question. Let's first simplify this a bit
static class Parent {
public int x = 1;
}
static class Child extends Parent {
public int x = 2;
}
public static void main(String[] args) {
Child c = new Child();
Parent p = c;
System.out.println(c.x);
System.out.println(p.x);
}
What do you think this will print?
It will be 2 1Instance variables are inherited, but they are not overridable. This is called hiding, Parent’s x is hidden by Child’s x. Instance variables are inherited, but they are not overridable. This is called hiding, Parent’s x is hidden by Child’s x.
The second line though… Where are we pulling x from? We do have a Parent reference, but it’s pointing to a Child instance, right? It’s like Child has two different variables with the same name; one it declares, one it inherits. Does it?
Arrays.stream(Child.class.getFields())
.map(Field::getName)
.forEachOrdered(System.out::println); // x x
It’s like Child has two fully qualified variables and depending on the reference you can access one or the other.
Now to your example (a bit simplified):
interface First {
int x = 3;
}
interface Second {
int x = 4;
}
static class Impl implements First, Second {}
What do you think this will print?
Arrays.stream(Impl.class.getFields())
.map(Field::getName)
.forEachOrdered(System.out::println);
As in the previous example, it will print x twice, the meaning of this is explained above.
Knowing this, let's go to your question (again, a bit simplified):
interface First {
int x = 1;
}
interface Second {
int x = 2;
}
class Impl implements First, Second {
}
Field left = First.class.getField("x");
// you might think that this will fail, since Impl has two variables x...
Field right = Impl.class.getField("x");
if (!left.equals(right)) {
throw new AssertionError("Aren't they equal?");
}
As the way this is written right now, this will NOT throw the AssertionError.
The idea here is that Field#equals uses 3 things for equality: type, name and declaringClass. The first two obviously match, so all we care about is the last one. And this is where the JLS comes at help which the other answer has already provided.
That is the reason btw, that if you change the order of interface declarations : class Impl implements Second, First that code will throw the AssertionError. Because now, x will be resolved from Second (in the order of the declaration... ), but we compare it with First.

How to reference a shadowed variable in the superclass of a superclass?

This is a simple example of inheritance where there is a shadowed variable x.
class A{
int x=1;
}
class B extends A{
int x=2;
}
class C extends B{
int x=3;
int y;
}
How can I reference the shadowed variable x of class A in class C?(I want something like y=super.super.x; that works well.)
Not as hard as you might think. (While I strongly encourage avoiding this situation,) if you have a class C that inherits from class B, which in turn inherits from class A, all of which implement a public field x, then using super is usually the wrong way to go about it.
Instead, given class C, try this:
((A)this).x; //don't forget the parentheses!
that will give you the value of x for A. Also,
super.x == ((B)this).x;
which is generally why, for single steps, we usually just use super.
Hopefully that helps.
To my knowledge, there is no way to achieve this the way you imagine. Your best bet would be to implement an access method in your class B:
class B extends A{
int x=2;
protected int getXFromA() {
return super.x;
}
}
This way you would be able to access the value of x as defined in class A from class C.
I would be very interested in your use case, though. Considering object oriented design, what reason could there be to directly access A's members from C? If this is the case, from an OOP perspective, C could not really be considered a proper subclass of B anymore.
class A {
int x = 1;
}
class B extends A {
int x = 2;
}
class C extends B {
int x = 3;
int y = ((A) this).x;
}
Note that shadowing is generally discouraged due to the confusion it can cause.

Is "inherited" the correct term to explain static method of superclass can be accessed by subclass?

Clarification: this question is not about access modifier
Confirmed that B.m() and b.m() statements both works in the following code:
class A {
static void m() { //some code }
}
class B extends A {
}
class Example {
public static void main (String [] args) {
B.m(); // running A's m() static method
}
public void try() {
B b = new B();
b.m(); // running A's m() static method
}
}
My question is can we said "static method is inherited"?
if "inherited" is the correct term, if we add a method to B class we same signature of the static class:
class A {
static void m() { //some code }
}
class B extends A {
static void m() { //some code }
}
class Example {
public static void main (String [] args) {
B.m(); // running B's m() static method
}
public void try() {
B b = new B();
b.m(); // running B's m() static method
A a = new B();
a.m(); // running A's m() static method, no polymorphism
}
}
In this case, notice that we have no polymorphism, is it the correct term to said that "static method is inherited but not overridden, subclass static method hide superclass static method"?
Last doubt, for these 2 terms, "inherited" and "overriden", which one is directly tied to the term "polymorphism" ?
Yes, I think "inherit" is the correct term here, even if it's not as descriptive as it might be. From section 8.4.8 of the Java Language Specification:
A class C inherits from its direct superclass and direct superinterfaces all non-private methods (whether abstract or not) of the superclass and superinterfaces that are public, protected or declared with default access in the same package as C and are neither overridden (§8.4.8.1) nor hidden (§8.4.8.2) by a declaration in the class.
That doesn't specify instance methods, but there are specific restrictions on what is allowed to hide or override what, which wouldn't make sense if static methods were not inherited.
Really though, I would simply view static methods as "accessible without qualification" rather than anything else, given that they don't take part in polymorphism etc. I think it's worth being very clear about that - for example, one static method can hide an inherited one, but it can't override it.
In other words, while I think "inherit" is technically correct, I would try to avoid using it without any further explanation.
For your second question, I'd say that based on the above, overriding is tied to polymorphism, but inheriting isn't necessarily.
(I would also strongly advise you to avoid calling static methods "via" variables, and also to use the name of the class which declares the static method wherever you specify the name at all. I know that's not part of the question, but I thought I'd just add it anyway...)
I think trying to apply words like 'inherited' and 'overridden' to this sort of thing is not productive. It's misleading because it gives the impression there is something comparable of what goes on with virtual instance methods, and you point out there isn't.
(But as Jon Skeet points out, the Java language spec doesn't agree with me, it groups these together in the same section.)
Guys I would like to share my knowledge in java with all java lovers out there!
First of all let me tell you that static members are those members which can be accessed directly without creating an object of that particular class, when static members of a class is used in some other class then it should be used by specifying the class name .(dot) static member's name(e.g. A.i in the following example), and also if any subclass class is getting inherited from a super class which has static members and if both subclass and super class are in the same package then that static members can be accessed from the base class without even using the class name of the super class. Please go through the
Example:
package myProg;
class A
{
static int i = 10;
A()
{
System.out.println("Inside A()");
}
}
class B extends A
{
public static void main(String[] args)
{
System.out.println("i = " + i); //accessing 'i' form superclass without specifying class name
System.out.println("A.i = " + A.i); //again accessing 'i' with the class name .(dot) static member 'i'
/*
we can also use the super class' object in order to access the static member compiler
will not show any error but it is not the exact way of using static members. static members are created
so that it could be used without creating the class object. see below the usage of object to use the
static member i.
*/
A obj = new A(); //creating class A object and A() also gets called
obj.i = 20;
System.out.println("obj.i = " + obj.i);
}
}
/*
This program was to show the usage of static member. Now, lets discuss on the topic of static member inheritance.
SO GUYS I WOULD LIKE TO TELL YOU THAT STATIC MEMBERS ARE NOT INHERITED. This undermentioned program is
to show the inheritance of static members.
*/
class A
{
static int i = 10; //initially the value of i is 10
static int j = 20; //lets use one more static member int j, just to see the value of it through class A, and B
static
{
/*
This is static initialization block(SIB) of class A,
SIB gets executed first in the order of top to bottom only one time
when the class is loaded.
*/
System.out.println("A-SIB");
}
}
class B extends A
{
static
{
i = 12;//trying to modify the i's value to 12
System.out.println("B-SIB");
}
}
class D extends A
{
static int k = 15;
static
{
System.out.println("D-SIB");
}
}
class C
{
public static void main(String [] arhs)
{
System.out.println("D.k: " + D.k);
/*here we are trying to access the static member k from class D,
it will try to search this class and then that class
will be loaded first i.e. SIB of class D will be loaded and SOP
statement of class D will be printed first. When the class loading
is done then the compiler will search for the static int k in class
D and if found SOP statement will be executed with the value of k.
*/
/*
ONE GROUND RULE: as soon as the compiler see this statement the compiler will load
class D into the memory, loading of class into memory is nothing but
storing all the static members (i.e. static constant & SIBs) into the
memory.
*/
System.out.println("B.i: " + B.i);
/*Now, this is what we are talking about... we think that static int i's
value is there in class B and when we write B.i it compiles and executes
successfully BUT... there compiler is playing a major role at this statement...
Try to understand now... we know that class B is the subclass of class A
BUT when the compiler sees this statement it will first try to search
the static int i inside class B and it is not found there, then since it is
the subclass of A, the compiler will search in class A and it is found
there. NOW, WHEN STATIC INT I IS FOUND IN CLASS A THE COMPILER WILL CHANGE
THIS STATEMENT B.i TO A.i and the class B WILL NOT AT ALL BE LOADED INTO
THE MEMORY BECAUSE STATIC I IS ONLY PRESENT IN CLASS A. But in the previous
statement static int k is present inside class D so when we try to access k's value
the class D will be loaded into memory i.e. SIB will be executed and then
the SOP statement of the value of k. USING B.i IS NOT WRONG BUT COMPILER
ASSUMES THAT THE PROGRAMMER HAS MADE A MISTAKE AND IT REPLACES THE CLASS NAME
B.i TO A.i. Thus this show that static members are not inherited to the subclass.And
therefore the vaue of i will NOT BE CHANGE TO 12 AS YOU CAN SEE IN THE SIB OF
CLASS B, it will be 10 only..
*/
System.out.println("A.j: " + A.j);//this statement will be executed as it is, compiler will not make
System.out.println("A.i: " + A.i);//any modifications to these statements.
System.out.println("B.j: " + B.j);//again compiler will modify this statement from B.j to A.j
}
}
Guys if you still have any confusion mail me at this email-id:
pradeep_y2k#yahoo.co.in
Regards
Pradeep Kumar Tiwari
Ok static methods cannot be overridden but can be redefined in other words its called hiding
check this http://www.coderanch.com/how-to/java/OverridingVsHiding they explain pretty well

Categories

Resources