Java : Accessing Hidden Interface Field [duplicate] - java

This question already has answers here:
Java Field Hiding
(3 answers)
Closed 7 years ago.
How to access an interface's field (which is by default public, static and final) using the implementing class's instance (this or super or instanceName if possible) if the field is hidden?
package mypack;
public interface MyInterface {
String str = "MyInterface.str";
String inheritanceTest = "inherited";
}
The field that i want to access is str
The other field inheritanceTest is to prove that interface fields are in fact inherited (unlike interface static methods)
package mypack;
public class Child implements MyInterface {
// Hiding the field
String str = "Child.str";
// Access test.
public String getParentStr() {
String result = "";
// result = MyInterface.super.str; // No enclosing instance of the type MyInterface is accessible in scope
// result = super.str; //str cannot be resolved or is not a field
return result;
}
// A method to check if the field is inherited or not.
public String getInheritedString() {
return this.inheritanceTest;
}
}
Notes
I know that it is discouraged to access static members using an instance instead of accessing it statically (Type.staticMemberNameOrSignature).
As shown, static interface methods are not inherited while static interface fields are inherited.
Non commented lines do not generate any compile-time errors.
Commented lines which are trying to assign a value to the variable result are the ones generating compile-time errors (Added to the line)
I am not asking about how to access the interface field statically.
Clarifying The Question
Is it possible to access an interfaces field that have been hidden by the implementing class using an instance (instance keywords like this or super) of the class?

Is it possible to access an interfaces field that have been hidden by the implementing class using an instance (instance keywords like this or super) of the class?
Yes. Instead of using this or super, just use interface name to access it.
MyInterface.str

Related

How to access attributes of an object where the class has been defined from an attribute in Java? [duplicate]

This question already has answers here:
Get the class instance variables and print their values using reflection
(4 answers)
Closed 5 years ago.
I want a method which returns an Object which is given a class depnding on the value of the String that is passed through
public static Object createObject(String classname){
Object myobject = null;
try {
Class myclass = Class.forName(classname);
myobject = myclass.newInstance();
System.out.println(myobject.objectAttribute);
}catch(Exception e){
}
return myobject;
}
I want to then be able to print out an Attribute (e.g objectAttribute) that i know will be held by all possible classes that classname could represent. The possible classes are defined in separate files. But the compiler gives error cannot find symbol objectAttribute. How can i access an atribute of this object?
sorry for poorly worded question
Thanks for any Help
You can use getFields() method to access all the fields, e.g.:
Class myclass = Class.forName("ClassName");
Field[] fields = myclass.getDeclaredFields();
for(Field field : fields) {
System.out.println(field.getName());
}
As the compiler says, a java.lang.Object doesn't have an objectAttribute field, so you can't access it via an Object reference. If you have some known base class that provides this attribute you could just cast myobject to it:
System.out.println(((BaseClass) myobject).objectAttribute);
Otherwise, you could rely on reflection:
Field field = myclass.getField("objectAttribute");
System.out.println(field.get(myobject));

Access level aware dependency injection into inherited field

At work there is a process framework. It uses keys and containers to set parameters without the use of dedicated constructors (it's basically the type safe heterogeneous container pattern).
I recently added dependency injection.
Below you find a representative example (it lacks some null checks, access control, etc.)
private static void inject(Process instance, Container c) throws Exception
{
Class<?> reference = instance.getClass();
for (Field field : reference.getDeclaredFields())
{
Inject inject = field.getAnnotation(Inject.class);
Key<Object> key = new Key<>(inject.key());
field.set(instance, c.getObject(key));
}
}
The implementation is working, but now I need to enhance it in order to also inject into inherited fields.
I had no problem retrieving the type hierachy and all the annotated, inherited fields. But in order to comply with Java, I must not inject into every retrieved field.
Only when the field is:
public
protected
package-privated and declared in a class that has the same package as reference
private and declared in class that encloses reference, which has to be an inner class (non-static nested class).
Items 1 - 3 are easy to check for. I have difficulties with the last item. Is there an elegant solution?
I thougt about using java.lang.Class.isMemberClass() and comparing class names.
Currently my check looks like this
private static boolean accessAllowed(Class<?> reference, Field field)
{
int modifiers = field.getModifiers();
boolean hasAccess = Modifier.isPublic(modifiers);
hasAccess |= Modifier.isProtected(modifiers);
// TODO fix
hasAccess |= Modifier.isPrivate(modifiers) /* add check as defined in 4. */;
// no access and not private means field is package-private
if (!hasAccess && !Modifier.isPrivate(modifiers))
hasAccess = reference.getPackage().equals(field.getDeclaringClass().getPackage());
return hasAccess;
}
Is there an easy and/or efficient way to find out whether a class is enclosed by another class? Or is there another way to find out whether I am allowed to inject?
The following solution should handle the private case.
The derived class is reference, it tries to set members inherited from fieldDeclaringClass
static boolean hasPrivateAccessRelation(Class<?> reference, Class<?> fieldDeclaringClass)
{
boolean isMemberClass = reference.isMemberClass();
boolean isEnclosingClass = reference.getName().contains(fieldDeclaringClass.getName());
// static nested classes can't access private members of enclosing class
return isMemberClass && isEnclosingClass && !Modifier.isStatic(reference.getModifiers());
}
The code works if the derived class is a inner class of fieldDeclaringClass. It fails if it is a static nested classes, since these have no access to private fields of enclosing classes.
A previous check is necessary to make sure reference and fieldDeclaringClass are not equal. Because in that case static would be a valid modifier, since a nested class always has access to its own fields.

What is the purpose of static keyword in this simple example? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
When should a method be static?
Usually when writing a static method for a class, the method can be accessed using ClassName.methodName. What is the purpose of using 'static' in this simple example and why should/should not use it here? also does private static defeat the purpose of using static?
public class SimpleTest {
public static void main(String[] args) {
System.out.println("Printing...");
// Invoke the test1 method - no ClassName.methodName needed but works fine?
test1(5);
}
public static void test1(int n1) {
System.out.println("Number: " + n1.toString());
}
//versus
public void test2(int n1) {
System.out.println("Number: " + n1.toString());
}
//versus
private static void test3(int n1) {
System.out.println("Number: " + n1.toString());
}
}
I had a look at a few tutorials. E.g. http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
My understanding of it is that instead of creating an instance of a class to use that method, you can just use the class name - saves memory in that certain situations there is no point in constructing an object every time to use a particular method.
The purpose of the static keyword is to be able to use a member without creating an instance of the class.
This is what happens here; all the methods (including the private ones) are invoked without creating an instance of SimpleTest.
In this Example,Static is used to directly to access the methods.A private static method defeats the purpose of "Data hiding".
Your main can directly call test1 method as it is also Static,it dosn't require any object to communicate.Main cannot refer non-static members,or any other non-static member cannot refer static member.
"non-static members cannot be referred from a static context"
You can refer This thread for more info about Static members.
static means that the function doesn't require an instance of the class to be called. Instead of:
SimpleTest st = new SimpleTest();
st.test2(5);
you can call:
SimpleTest.test1(5);
You can read more about static methods in this article.
A question about private static has already been asked here. The important part to take away is this:
A private static method by itself does not violate OOP per se, but when you have a lot of these methods on a class that don't need (and cannot*) access instance fields, you are not programming in an OO way, because "object" implies state + operations on that state defined together. Why are you putting these methods on that class, if they don't need any state? -eljenso
static means that the method is not associated with an instance of the class.
It is orthogonal to public/protected/private, which determine the accessibility of the method.
Calling test1 from main in your example works without using the class name because test1 is a static method in the same class as main. If you wanted to call test2 from main, you would need to instantiate an object of that class first because it is not a static method.
A static method does not need to be qualified with a class name when that method is in the same class.
That a method is private (static or not) simply means it can't be accessed from another class.
An instance method (test2 in your example) can only be called on an instance of a class, i.e:
new SimpleTest().test2(5);
Since main is a static method, if you want to call a method of the class without having to instantiate it, you need to make those methods also static.
In regards to making a private method static, it has more readability character than other. There isn't really that much of a difference behind the hoods.
You put in static methods all the computations which are not related to a specific instance of your class.
About the visibility, public static is used when you want to export the functionality, while private static is intended for instance-independent but internal use.
For instance, suppose that you want to assign an unique identifier to each instance of your class. The counter which gives you the next id isn't related to any specific instance, and you also don't want external code to modify it. So you can do something like:
class Foo {
private static int nextId = 0;
private static int getNext () {
return nextId ++;
}
public final int id;
public Foo () {
id = getNext(); // Equivalent: Foo.getNext()
}
}
If in this case you want also to know, from outside the class, how many instances have been created, you can add the following method:
public static int getInstancesCount () {
return nextId;
}
About the ClassName.methodName syntax: it is useful because it specifies the name of the class which provides the static method. If you need to call the method from inside the class you can neglect the first part, as the name methodName would be the closest in terms of namespace.

Unexpected "transient" constructor modifier

I found interesting thing while working with reflection. I tried to retrieve constructors of simple class and their modifiers.
public class Test {
public Test(Object... args) {}
}
Here is the code to retrieve constructor modifiers:
Class<?> clazz = Test.class;
Constructor<?>[] ctors = clazz.getDeclaredConstructors();
for (Constructor<?> ctor : ctors) {
int mod = ctor.getModifiers();
/*if not package-private modifier*/
if(mod!=0) {
System.out.println( Modifier.toString(mod)));
}
}
The result is:
public transient
If I pass to constructor not variable parameters, but just array, it's ok.
public class Test {
public Test(Object[] args) {}
}
The result is:
public
The same happens regardless of constructor modifier (public, protected, private) or parameters type (primitive or reference). How could it be, whereas "transient" is not valid modifier for constructor?
Access modifiers are encoded as bit masks inside the class file. The JVM spec assigns different meaning to some of the bits depending on whether they appear in a method modifier or a field modifier. Bit 7 (0x0080) is one such bit.
For methods:
ACC_VARARGS 0x0080 Declared with variable number of arguments.
For fields:
ACC_TRANSIENT 0x0080 Declared transient; not written or read by a persistent
object manager.
Since you're looking at a method, the correct interpretation of this modifier is ACC_VARARGS and not ACC_TRANSIENT.
However, the Modifier class only appears capable of dealing with a subset of modifiers defined in the JVM spec. Because all it takes is an int, it's unable to tell ACC_VARARGS and ACC_TRANSIENT apart.

Accessing a Super's Member of different type with the same variable name

Consider the following superclass and subclass pair, how do you access the superclass member?
class Super {
Number aNumber;
}
class Subbie extends Super {
Float aNumber;
}
You can access the super Member by super.aNumber provided it is an instance of the Subclass.
Given that the attribute does not have a visiblity modifier, it is assumed to be package private. Subbie will only be able to access Super's aNumber if they're in the same package.
If it was, you could access it like this: super.aNumber. Notice super here is a keyword that implicitly refers to the superclass, and doesn't have anything to do with the superclass being named Super.
class Super {
Number aNumber;
}
class Subbie extends Super {
Float aNumber;
public Number getNumberFromSuper() {
return super.aNumber;
}
}
I'd suggest to take a read on the excellent Java tutorials online, for instance:
Inheritance
Controlling Access to Members of a Class
You can define a field with different keywords known as Access Modifiers (check the links at the end for a detailed explanation on this topic), each one defining a scope for access/use. I'll focus this explanation on fields.
Public: Accessible by everyone. This Access Modifier is regulary used with methods and not with fields. In Java, it is encouraged the use of get and set methods to access the value of a field and change it (respectively). You can access a field this way:
AClass c = new AClass();
c.publicField = 3; //Setting a value in a field, int in this case
int sum = c.publicField + 4; //Obtaining the value of publicField to use it
Private: Definining a field as private makes it visible only to the class itself, meaning no one outside the boundaries of a class will be able to see that field. A common class in Java usually has private fields and accessors (get & set methods).
public class AClass {
public int publicField;
private String privateField = "Can't see me!";
public String getPrivateField() {
return privateField;
}
public void setPrivateField(String newValue) {
privateField = newVaule;
}
}
Getters and Setters let you control the access to your private fields, allowing you to perform any logic you desire before updating the value of that field or preparing a field in a particular before returning its value if you need it.
Protected: Only subclasses of a class and classes in the same package can access a field defined with this keyword. In your case Subbie has access to the protected fields of Super and any other class in the same package as Super has access to those fields as well.
No Access Modifier: This is your current case and the answer to your question relies strongly on the structure of your classes. If they are in the same package, then you can access Super's field from Subbie. Otherwise, if Subbie is in another package, you won't be able to access that field. This field is referenced as Package-Private.
Some related articles you might want to check:
Inheritance in Java
Controlling the Access to Members of a Class

Categories

Resources