Using reflection get a static private hashmap in java - java

I'm trying to find a way to extract a HashMap from a private static field within another class via Java.
eg.
Inside FooClass there is a static field that looks like this:
private Map entityRenderMap;
Then in its construct it has:
entityRenderMap = new HashMap();
How do you get the values within entityRenderMap via Reflection in Java? I've tried this but get errors:
cl = RenderManager.class.getDeclaredField("entityRenderMap");
cl.setAccessible(true);
Object foo = cl.get(this.entityRenderMap);
Mod.log(cl.getName());
The error I get is:
java.lang.IllegalArgumentException: Can not set java.util.Map field RenderManager.entityRenderMap to java.util.HashMap
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(Unknown Source)
at sun.reflect.UnsafeObjectFieldAccessorImpl.get(Unknown Source

First, your code doesn't match your explanation. Is it really a static field or is it not (your code says it's not)?
If it is static, you should pass null as argument to cl.get() (you don't need an instance to access static members).
However, I suspect that your field is actually not static, and your passing the wrong instance to cl.get(). The JavaDocs to Field.get() state it would throw an IllegalArgumentException in this case. You need to pass a RenderManager instance to this method. Your code looks like your passing a Map (the entityRenderMap).
And last, is this code inside your RenderManager class? I suspect this, because your accessing a field with this with the same name as the field you want to set. In this case, don't use reflection at all!

Are you certain it is a static field. The javadoc of the get method clearly states:
If the underlying field is a static field, the obj argument is ignored; it may be null.
Otherwise, the underlying field is an instance field. If the specified obj argument is null, the method throws a NullPointerException. If the specified object is not an instance of the class or interface declaring the underlying field, the method throws an IllegalArgumentException.
So with a static field you would not get the IllegalArgumentException since the parameter is ignored. Further, the code you posted shows it is not a static field but a regular field (since it lacks the word static, and its initialized in the constructor).
If you want to access the field of a certain instance A, you should pass that instance A to the Field#get method, and not the A.field as you are trying to do with your cl.get(this.entityRenderMap) call.
You can take a look at this tutorial for some examples

If the field is really static, you should pass null as an argument to cl.get().
If the field is not static, then you must pass the instance of FooClass which you want to get the field value from:
FooClass fc = new FooClass(); // or whatever, provided that fc is a FooClass instance
Object foo = cl.get(fc);

I'm assuming cl is a java.lang.reflect.Field. The documentation states that Fields' get-method will throw:
IllegalArgumentException - if the specified object is not an instance
of the class or interface declaring the underlying field (or a
subclass or implementor thereof).
You should be passing the RenderManager-object to the get-method instead of the field (unless it's static, which it is not according to your example).

vim Test.java
import java.util.*;
import com.dp4j.*;
class FooClass{
private static Map entityRenderMap;
FooClass(){
entityRenderMap = new HashMap();
}
}
public class Test{
#Reflect
public static void main(String... args){
Map reflectEntityMap = FooClass.entityRenderMap;
}
}
javac -cp ~/ws/dp4j/dp4j.jar -Averbose=true Test.java
Test.java:16: Note:
import java.util.*;
import com.dp4j.*;
class FooClass {
private static Map entityRenderMap;
FooClass() {
entityRenderMap = new HashMap();
}
}
public class Test {
public Test() {
super();
}
#Reflect()
public static void main(String... args) throws java.lang.ClassNotFoundException, java.lang.NoSuchFieldException, java.lang.IllegalArgumentException, java.lang.IllegalAccessException {
java.lang.reflect.Field entityRenderMapField = null;
entityRenderMapField = Class.forName("FooClass").getDeclaredField("entityRenderMap");
entityRenderMapField.setAccessible(true);
Map reflectEntityMap;
reflectEntityMap = (.java.util.Map)entityRenderMapField.get("");
}
}

Related

Can I access the static variables of the 'Class' Object?

Having this method:
readAllTypes(Class clazz) {...}
Can I access the static variables of the class?
Yes. Just use Class.getDeclaredFields() (or Class.getDeclaredField(String)) as normal, and to get the values, use the Field.getXyz() methods, passing in null for the obj parameter.
Sample code:
import java.lang.reflect.Field;
class Foo {
public static int bar;
}
class Test {
public static void main(String[] args)
throws IllegalAccessException, NoSuchFieldException {
Field field = Foo.class.getDeclaredField("bar");
System.out.println(field.getInt(null)); // 0
Foo.bar = 10;
System.out.println(field.getInt(null)); // 10
}
}
You can find the field using clazz.getDeclaredFields(), which returns a Field[], or by directly getting the field by name, with clazz.getDeclaredField("myFieldName"). This may throw a NoSuchFieldException.
Once you've done that, you can get the value of the field with field.get(null) if the field represents an object, or with field.getInt(null), field.getDouble(null), etc. if it's a primitive. To check the type of the field, use the getType or getGenericType. These may throw an IllegalAccessException if they're not public, in which case you can use field.setAccessible(true) first. You can also set the fields in the same way if you just replace "get" with "set".

Using Java reflections to get class variables

I have the following class:
public final class ClassMap {
public static final Class HELLO = HelloActivity.class;
}
I want to be able to access HelloActivity.class knowing the string "HELLO". I've tried the following:
Field classField = ClassMap.class.getField("HELLO");
But that returns a Field object. How can I get a Class object back?
Thanks!
Now that you have the Field object representing the field, ask for the value, i.e. call classField.get(Object obj).
Since your field is static, the obj parameter will be ignored, and you should just give a null value. Javadoc says so:
If the underlying field is a static field, the obj argument is ignored; it may be null.
So, do this:
Field classField = ClassMap.class.getField("HELLO");
Object value = classField.get(null);

Why doesn't calling a static variable chained from a static method that returns null throw a NPE?

I have the following code
public class Test {
static String mountain = "Everest";
static Test favorite() {
System.out.print("Mount ");
return null;
}
public static void main(String[] args) {
System.out.println(favorite().mountain);
}
}
I thought it would raise a NPE but it is giving Mount Everest as output can anyone clarify?
It just so happens that you can access static members on object references. In that case, the member is resolved according to the type of the reference, not its value.
The Java Language Specification says this about field access of static members
If the field is a non-blank final field, then the result is the value
of the specified class variable in the class or interface that is the
type of the Primary expression.
If the field is not final, or is a blank final and the field access
occurs in a constructor, then the result is a variable, namely, the
specified class variable in the class that is the type of the Primary
expression.
So the Primary, the instance, does not matter.
When you access a static member on an instance of a class, the Java compiler completely ignores the runtime value (and even class) of the variable and uses the member belonging to the declared class. In this case, your code is equivalent to:
favorite();
System.out.println(Test.mountain);
Even if you had code like this:
public class SubTest extends Test {
static String mountain = "Kilimanjaro";
}
...
Test foo = new SubTest();
System.out.println(foo.mountain);
you'll still get the value on the Test class.
favorite() is a static method that returns Test type. Then you use the static variable of this class (mountain). This all works as you never use (and do not need to use) an instance of this class so there can be no null pointer exception.

How does the "final" keyword in Java work? (I can still modify an object.)

In Java we use final keyword with variables to specify its values are not to be changed.
But I see that you can change the value in the constructor / methods of the class. Again, if the variable is static then it is a compilation error.
Here is the code:
import java.util.ArrayList;
import java.util.List;
class Test {
private final List foo;
public Test()
{
foo = new ArrayList();
foo.add("foo"); // Modification-1
}
public static void main(String[] args)
{
Test t = new Test();
t.foo.add("bar"); // Modification-2
System.out.println("print - " + t.foo);
}
}
Above code works fine and no errors.
Now change the variable as static:
private static final List foo;
Now it is a compilation error. How does this final really work?
This is a favorite interview question. With this questions, the interviewer tries to find out how well you understand the behavior of objects with respect to constructors, methods, class variables (static variables) and instance variables.
Now a days interviewers are asking another favorite question what is effectively final from java 1.8. I will explain in the end about this effectively final in java 1.8.
import java.util.ArrayList;
import java.util.List;
class Test {
private final List foo;
public Test() {
foo = new ArrayList();
foo.add("foo"); // Modification-1
}
public void setFoo(List foo) {
//this.foo = foo; Results in compile time error.
}
}
In the above case, we have defined a constructor for 'Test' and gave it a 'setFoo' method.
About constructor: Constructor can be invoked only one time per object creation by using the new keyword. You cannot invoke constructor multiple times, because constructor are not designed to do so.
About method: A method can be invoked as many times as you want (Even never) and the compiler knows it.
Scenario 1
private final List foo; // 1
foo is an instance variable. When we create Test class object then the instance variable foo, will be copied inside the object of Test class. If we assign foo inside the constructor, then the compiler knows that the constructor will be invoked only once, so there is no problem assigning it inside the constructor.
If we assign foo inside a method, the compiler knows that a method can be called multiple times, which means the value will have to be changed multiple times, which is not allowed for a final variable. So the compiler decides constructor is good choice! You can assign a value to a final variable only one time.
Scenario 2
private static final List foo = new ArrayList();
foo is now a static variable. When we create an instance of Test class, foo will not be copied to the object because foo is static. Now foo is not an independent property of each object. This is a property of Test class. But foo can be seen by multiple objects and if every object which is created by using the new keyword which will ultimately invoke the Test constructor which changes the value at the time of multiple object creation (Remember static foo is not copied in every object, but is shared between multiple objects.)
Scenario 3
t.foo.add("bar"); // Modification-2
Above Modification-2 is from your question. In the above case, you are not changing the first referenced object, but you are adding content inside foo which is allowed. Compiler complains if you try to assign a new ArrayList() to the foo reference variable.
Rule If you have initialized a final variable, then you cannot change it to refer to a different object. (In this case ArrayList)
final classes cannot be subclassed
final methods cannot be overridden. (This method is in superclass)
final methods can override. (Read this in grammatical way. This method is in a subclass)
Now let's see what is effectively final in java 1.8?
public class EffectivelyFinalDemo { //compile code with java 1.8
public void process() {
int thisValueIsFinalWithoutFinalKeyword = 10; //variable is effectively final
//to work without final keyword you should not reassign value to above variable like given below
thisValueIsFinalWithoutFinalKeyword = getNewValue(); // delete this line when I tell you.
class MethodLocalClass {
public void innerMethod() {
//below line is now showing compiler error like give below
//Local variable thisValueIsFinalWithoutFinalKeyword defined in an enclosing scope must be final or effectively final
System.out.println(thisValueIsFinalWithoutFinalKeyword); //on this line only final variables are allowed because this is method local class
// if you want to test effectively final is working without final keyword then delete line which I told you to delete in above program.
}
}
}
private int getNewValue() {
return 0;
}
}
Above program will throw error in java 1.7 or <1.8 if you do not use final keyword. Effectively final is a part of Method Local Inner classes. I know you would rarely use such effectively final in method local classes, but for interview we have to be prepared.
You are always allowed to initialize a final variable. The compiler makes sure that you can do it only once.
Note that calling methods on an object stored in a final variable has nothing to do with the semantics of final. In other words: final is only about the reference itself, and not about the contents of the referenced object.
Java has no concept of object immutability; this is achieved by carefully designing the object, and is a far-from-trivial endeavor.
Final keyword has a numerous way to use:
A final class cannot be subclassed.
A final method cannot be overridden by subclasses
A final variable can only be initialized once
Other usage:
When an anonymous inner class is defined within the body of a method,
all variables declared final in the scope of that method are
accessible from within the inner class
A static class variable will exist from the start of the JVM, and should be initialized in the class. The error message won't appear if you do this.
The final keyword can be interpreted in two different ways depending on what it's used on:
Value types: For ints, doubles etc, it will ensure that the value cannot change,
Reference types: For references to objects, final ensures that the reference will never change, meaning that it will always refer to the same object. It makes no guarantees whatsoever about the values inside the object being referred to staying the same.
As such, final List<Whatever> foo; ensures that foo always refers to the same list, but the contents of said list may change over time.
If you make foo static, you must initialize it in the class constructor (or inline where you define it) like the following examples.
Class constructor (not instance):
private static final List foo;
static
{
foo = new ArrayList();
}
Inline:
private static final List foo = new ArrayList();
The problem here is not how the final modifier works, but rather how the static modifier works.
The final modifier enforces an initialization of your reference by the time the call to your constructor completes (i.e. you must initialize it in the constructor).
When you initialize an attribute in-line, it gets initialized before the code you have defined for the constructor is run, so you get the following outcomes:
if foo is static, foo = new ArrayList() will be executed before the static{} constructor you have defined for your class is executed
if foo is not static, foo = new ArrayList() will be executed before your constructor is run
When you do not initilize an attribute in-line, the final modifier enforces that you initialize it and that you must do so in the constructor. If you also have a static modifier, the constructor you will have to initialize the attribute in is the class' initialization block : static{}.
The error you get in your code is from the fact that static{} is run when the class is loaded, before the time you instantiate an object of that class. Thus, you will have not initialized foo when the class is created.
Think of the static{} block as a constructor for an object of type Class. This is where you must do the initialization of your static final class attributes (if not done inline).
Side note:
The final modifier assures const-ness only for primitive types and references.
When you declare a final object, what you get is a final reference to that object, but the object itself is not constant.
What you are really achieving when declaring a final attribute is that, once you declare an object for your specific purpose (like the final List that you have declared), that and only that object will be used for that purpose: you will not be able to change List foo to another List, but you can still alter your List by adding/removing items (the List you are using will be the same, only with its contents altered).
This is a very good interview question. Sometimes they might even ask you what is the difference between a final object and immutable object.
1) When someone mentions a final object, it means that the reference cannot be changed, but its state(instance variables) can be changed.
2) An immutable object is one whose state can not be changed, but its reference can be changed.
Ex:
String x = new String("abc");
x = "BCG";
ref variable x can be changed to point a different string, but value of "abc" cannot be changed.
3) Instance variables(non static fields) are initialized when a constructor is called. So you can initialize values to you variables inside a constructor.
4) "But i see that you can change the value in the constructor/methods of the class". -- You cannot change it inside a method.
5) A static variable is initialized during class loading. So you cannot initialize inside a constructor, it has to be done even before it. So you need to assign values to a static variable during declaration itself.
The final keyword in java is used to restrict the user. The java final keyword can be used in many context. Final can be:
variable
method
class
The final keyword can be applied with the variables, a final variable that has no value, is called blank final variable or uninitialized final variable. It can be initialized in the constructor only. The blank final variable can be static also which will be initialized in the static block only.
Java final variable:
If you make any variable as final, you cannot change the value of final variable(It will be constant).
Example of final variable
There is a final variable speedlimit, we are going to change the value of this variable, but It can't be changed because final variable once assigned a value can never be changed.
class Bike9{
final int speedlimit=90;//final variable
void run(){
speedlimit=400; // this will make error
}
public static void main(String args[]){
Bike9 obj=new Bike9();
obj.run();
}
}//end of class
Java final class:
If you make any class as final, you cannot extend it.
Example of final class
final class Bike{}
class Honda1 extends Bike{ //cannot inherit from final Bike,this will make error
void run(){
System.out.println("running safely with 100kmph");
}
public static void main(String args[]){
Honda1 honda= new Honda();
honda.run();
}
}
Java final method:
If you make any method as final, you cannot override it.
Example of final method
(run() in Honda cannot override run() in Bike)
class Bike{
final void run(){System.out.println("running");}
}
class Honda extends Bike{
void run(){System.out.println("running safely with 100kmph");}
public static void main(String args[]){
Honda honda= new Honda();
honda.run();
}
}
shared from:
http://www.javatpoint.com/final-keyword
Worth to mention some straightforward definitions:
Classes/Methods
You can declare some or all of a class methods as final, in order to indicate that the method cannot be overridden by subclasses.
Variables
Once a final variable has been initialized, it always contains the same value.
final basically avoid overwrite/superscribe by anything (subclasses, variable "reassign"), depending on the case.
"A final variable can only be assigned once"
*Reflection* - "wowo wait, hold my beer".
Freeze of final fields happen in two scenarios:
End of constructor.
When reflection sets the field's value. (as many times as it wants to)
Let's break the law
public class HoldMyBeer
{
final int notSoFinal;
public HoldMyBeer()
{
notSoFinal = 1;
}
static void holdIt(HoldMyBeer beer, int yetAnotherFinalValue) throws Exception
{
Class<HoldMyBeer> cl = HoldMyBeer.class;
Field field = cl.getDeclaredField("notSoFinal");
field.setAccessible(true);
field.set(beer, yetAnotherFinalValue);
}
public static void main(String[] args) throws Exception
{
HoldMyBeer beer = new HoldMyBeer();
System.out.println(beer.notSoFinal);
holdIt(beer, 50);
System.out.println(beer.notSoFinal);
holdIt(beer, 100);
System.out.println(beer.notSoFinal);
holdIt(beer, 666);
System.out.println(beer.notSoFinal);
holdIt(beer, 8888);
System.out.println(beer.notSoFinal);
}
}
Output:
1
50
100
666
8888
The "final" field has been assigned 5 different "final" values (note the quotes). And it could keep being assigned different values over and over...
Why? Because reflection is like Chuck Norris, and if it wants to change the value of an initialized final field, it does. Some say he himself is the one that pushes the new values into the stack :
Code:
7: astore_1
11: aload_1
12: getfield
18: aload_1
19: bipush 50 //wait what
27: aload_1
28: getfield
34: aload_1
35: bipush 100 //come on...
43: aload_1
44: getfield
50: aload_1
51: sipush 666 //...you were supposed to be final...
60: aload_1
61: getfield
67: aload_1
68: sipush 8888 //ok i'm out whatever dude
77: aload_1
78: getfield
final is a reserved keyword in Java to restrict the user and it can be applied to member variables, methods, class and local variables. Final variables are often declared with the static keyword in Java and are treated as constants. For example:
public static final String hello = "Hello";
When we use the final keyword with a variable declaration, the value stored inside that variable cannot be changed latter.
For example:
public class ClassDemo {
private final int var1 = 3;
public ClassDemo() {
...
}
}
Note: A class declared as final cannot be extended or inherited (i.e, there cannot be a subclass of the super class). It is also good to note that methods declared as final cannot be overridden by subclasses.
Benefits of using the final keyword are addressed in this thread.
First of all, the place in your code where you are initializing (i.e. assigning for the first time) foo is here:
foo = new ArrayList();
foo is an object (with type List) so it is a reference type, not a value type (like int). As such, it holds a reference to a memory location (e.g. 0xA7D2A834) where your List elements are stored. Lines like this
foo.add("foo"); // Modification-1
do not change the value of foo (which, again, is just a reference to a memory location). Instead, they just add elements into that referenced memory location. To violate the final keyword, you would have to try to re-assign foo as follows again:
foo = new ArrayList();
That would give you a compilation error.
Now, with that out of the way, think about what happens when you add the static keyword.
When you do NOT have the static keyword, each object that instantiates the class has its own copy of foo. Therefore, the constructor assigns a value to a blank, fresh copy of the foo variable, which is perfectly fine.
However, when you DO have the static keyword, only one foo exists in memory that is associated with the class. If you were to create two or more objects, the constructor would be attempting to re-assign that one foo each time, violating the final keyword.
Suppose you have two moneyboxes, red and white. You assign these moneyboxes only two children and they are not allowed interchange their boxes. So You have red or white moneyboxes(final) you cannot modify the box but you can put money on your box.Nobody cares (Modification-2).
Read all the answers.
There is another user case where final keyword can be used i.e. in a method argument:
public void showCaseFinalArgumentVariable(final int someFinalInt){
someFinalInt = 9; // won't compile as the argument is final
}
Can be used for variable which should not be changed.
When you make it static final it should be initialized in a static initialization block
private static final List foo;
static {
foo = new ArrayList();
}
public Test()
{
// foo = new ArrayList();
foo.add("foo"); // Modification-1
}
The final keyword indicates that a variable may only be initialized once. In your code you are only performing one initialization of final so the terms are satisfied. This statement performs the lone initialization of foo. Note that final != immutable, it only means that the reference cannot change.
foo = new ArrayList();
When you declare foo as static final the variable must be initialized when the class is loaded and cannot rely on instantiation (aka call to constructor) to initialize foo since static fields must be available without an instance of a class. There is no guarantee that the constructor will have been called prior to using the static field.
When you execute your method under the static final scenario the Test class is loaded prior to instantiating t at this time there is no instantiation of foo meaning it has not been initialized so foo is set to the default for all objects which is null. At this point I assume your code throws a NullPointerException when you attempt to add an item to the list.
Since the final variable is non-static, it can be initialized in constructor. But if you make it static it can not be initialized by constructor (because constructors are not static).
Addition to list is not expected to stop by making list final. final just binds the reference to particular object. You are free to change the 'state' of that object, but not the object itself.
Following are different contexts where final is used.
Final variables A final variable can only be assigned once. If the variable is a reference, this means that the variable cannot be re-bound to reference another object.
class Main {
public static void main(String args[]){
final int i = 20;
i = 30; //Compiler Error:cannot assign a value to final variable i twice
}
}
final variable can be assigned value later (not compulsory to assigned a value when declared), but only once.
Final classes A final class cannot be extended (inherited)
final class Base { }
class Derived extends Base { } //Compiler Error:cannot inherit from final Base
public class Main {
public static void main(String args[]) {
}
}
Final methods A final method cannot be overridden by subclasses.
//Error in following program as we are trying to override a final method.
class Base {
public final void show() {
System.out.println("Base::show() called");
}
}
class Derived extends Base {
public void show() { //Compiler Error: show() in Derived cannot override
System.out.println("Derived::show() called");
}
}
public class Main {
public static void main(String[] args) {
Base b = new Derived();;
b.show();
}
}
I thought of writing an updated and in depth answer here.
final keyword can be used in several places.
classes
A final class means that no other class can extend that final class. When Java Run Time (JRE) knows an object reference is in type of a final class (say F), it knows that the value of that reference can only be in type of F.
Ex:
F myF;
myF = new F(); //ok
myF = someOther; //someOther cannot be in type of a child class of F.
//because F cannot be extended.
So when it executes any method of that object, that method doesn't need to be resolved at run time using a virtual table. i.e. run-time polymorphism cannot be applied. So the run time doesn't bother about that. Which means it saves processing time, which will improve performance.
methods
A final method of any class means that any child class extending that class cannot override that final method(s). So the run time behavior in this scenario is also quite same with the previous behavior I mentioned for classes.
fields, local variables, method parameters
If one specified any kind of above as final, it means that the value is already finalized, so the value cannot be changed.
Ex:
For fields, local parameters
final FinalClass fc = someFC; //need to assign straight away. otherwise compile error.
final FinalClass fc; //compile error, need assignment (initialization inside a constructor Ok, constructor can be called only once)
final FinalClass fc = new FinalClass(); //ok
fc = someOtherFC; //compile error
fc.someMethod(); //no problem
someOtherFC.someMethod(); //no problem
For method parameters
void someMethod(final String s){
s = someOtherString; //compile error
}
This simply means that value of the final reference value cannot be changed. i.e. only one initialization is allowed. In this scenario, in run time, since JRE knows that values cannot be changed, it loads all these finalized values (of final references) into L1 cache. Because it doesn't need to load back again and again from main memory. Otherwise it loads to L2 cache and does time to time loading from main memory. So it is also a performance improvement.
So in all above 3 scenarios, when we have not specified the final keyword in places we can use, we don't need to worry, compiler optimizations will do that for us. There are also lots of other things that compiler optimizations do for us. :)
Above all are correct. Further if you do not want others to create sub classes from your class, then declare your class as final. Then it becomes the leaf level of your class tree hierarchy that no one can extend it further. It is a good practice to avoid huge hierarchy of classes.
I can only say in answer to your question that in this case you can't change reference value of foo. You just simply put value into the same reference, that's why you can add value into the foo reference. This problem is occur you can't understand very well difference between reference value and primitive value. Reference value is also a value which store object address(this is value) in heap memory.
public static void main(String[] args)
{
Test t = new Test();
t.foo.add("bar"); // Modification-2
System.out.println("print - " + t.foo);
}
but in this case you can see that if you try to write in the following code you will see that compile time error will occur.
public static void main(String[] args)
{
Main main = new Main();
main.foo=new ArrayList<>();//Cannot assign a value to final variable 'foo'
System.out.println("print - " + main.foo);
}

Getting value of public static final field/property of a class in Java via reflection

Say I have a class:
public class R {
public static final int _1st = 0x334455;
}
How can I get the value of the "_1st" via reflection?
First retrieve the field property of the class, then you can retrieve the value. If you know the type you can use one of the get methods with null (for static fields only, in fact with a static field the argument passed to the get method is ignored entirely). Otherwise you can use getType and write an appropriate switch as below:
Field f = R.class.getField("_1st");
Class<?> t = f.getType();
if(t == int.class){
System.out.println(f.getInt(null));
}else if(t == double.class){
System.out.println(f.getDouble(null));
}...
R.class.getField("_1st").get(null);
Exception handling is left as an exercise for the reader.
Basically you get the field like any other via reflection, but when you call the get method you pass in a null since there is no instance to act on.
This works for all static fields, regardless of their being final. If the field is not public, you need to call setAccessible(true) on it first, and of course the SecurityManager has to allow all of this.
I was following the same route (looking through the generated R class) and then I had this awful feeling it was probably a function in the Resources class. I was right.
Found this:
Resources::getIdentifier
Thought it might save people some time. Although they say its discouraged in the docs, which is not too surprising.
I was looking for how to get a private static field and landed here.
For fellow searchers, here is how:
public class R {
private static final int _1st = 0x334455;
}
class ReflectionHacking {
public static main(String[] args) {
Field field = R.class.getFieldDeclaration("_1st");
field.setAccessible(true);
int privateHidenInt = (Integer)field.get(null);
}
}

Categories

Resources