I have an autogenerated Java class that I'm using in a Scala application. Something like:
public class Model123123 extends GenModel {
public int nclasses() { return 4; }
// Names of columns used by model.
public static final String[] NAMES = NamesHolder_Model123123.VALUES;
I can create instances like this
val model = Class
.forName("Model123123")
.newInstance()
.asInstanceOf[GenModel]
I'd like to access the static members of this Java class. I can do it directly, like this:
Model123123.NAMES
but don't understand how to do it via reflection. I've tried:
scala> Class.forName("Model123123").NAMES
<console>:10: error: value NAMES is not a member of Class[?0]
Class.forName(model_name).NAMES
and
scala> model.getClass.NAMES
<console>:11: error: value NAMES is not a member of Class[?0]
model.getClass.NAMES
I don't know a ton about Java or scala reflection, so I'm a bit lost. I'm trying to do this via reflection as I will have many classes that subclass the same parent class and I'd like to change the class dynamically at runtime.
Thanks
it should be possible like this:
val clazz = Class.forName("Model123123")
val field = clazz.getDeclaredField("NAMES")
val value = field.get(null).asInstanceOf[Array[String]]
We get the class and ask for field in a same way as we would do for non-static field. Once we have the field we can get the value of it by calling get method. The null argument means that we are not passing it any instance from which it should get the value ( since it's static member). At last we have to manually cast the type to the type we're expecting, because type information is lost at this time.
If you need to update the value of static field you can do it as
field.set(null, Array[String]("name1", "name2"))
We again pass null since we don't need to set it on some specific instance since it's class member.
It's basically just java reflection used in the scala language. Another approach is to use scala mirrors - http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html
In your case, the best way is to cast model instance to a common interface hex.genmodel.GenModel as you did, then you can easily call getNames method to access names.
There is no need to use reflection to access static members.
Related
Consider the following example code
class MyClass {
public String var = "base";
public void printVar() {
System.out.println(var);
}
}
class MyDerivedClass extends MyClass {
public String var = "derived";
public void printVar() {
System.out.println(var);
}
}
public class Binding {
public static void main(String[] args) {
MyClass base = new MyClass();
MyClass derived = new MyDerivedClass();
System.out.println(base.var);
System.out.println(derived.var);
base.printVar();
derived.printVar();
}
}
it gives the following output
base
base
base
derived
Method calls are resolved at runtime and the correct overridden method is called, as expected.
The variables access is instead resolved at compile time as I later learned.
I was expecting an output as
base
derived
base
derived
because in the derived class the re-definition of var shadows the one in the base class.
Why does the binding of variables happens at compile time and not at runtime? Is this only for performance reasons?
The reason is explained in the Java Language Specification in an example in Section 15.11, quoted below:
...
The last line shows that, indeed, the field that is accessed does not depend on the run-time class of the referenced object; even if s holds a reference to an object of class T, the expression s.x refers to the x field of class S, because the type of the expression s is S. Objects of class T contain two fields named x, one for class T and one for its superclass S.
This lack of dynamic lookup for field accesses allows programs to be run efficiently with straightforward implementations. The power of late binding and overriding is available, but only when instance methods are used...
So yes performance is a reason. The specification of how the field access expression is evaluated is stated as follows:
If the field is not static:
...
If the field is a non-blank final, then the result is the value of the named member field in type T found in the object referenced by the value of the Primary.
where Primary in your case refers the variable derived which is of type MyClass.
Another reason, as #Clashsoft suggested, is that in subclasses, fields are not overriden, they are hidden. So it makes sense to allow which fields to access based on the declared type or using a cast. This is also true for static methods. This is why the field is determined based on the declared type. Unlike overriding by instance methods where it depends on the actual type. The JLS quote above indeed mentions this reason implicitly:
The power of late binding and overriding is available, but only when instance methods are used.
While you might be right about performance, there is another reason why fields are not dynamically dispatched: You wouldn't be able to access the MyClass.var field at all if you had a MyDerivedClass instance.
Generally, I don't know about any statically typed language that actually has dynamic variable resolution. But if you really need it, you can make getters or accessor methods (which should be done in most cases to avoid public fields, anyway):
class MyClass
{
private String var = "base";
public String getVar() // or simply 'var()'
{
return this.var;
}
}
class MyDerivedClass extends MyClass {
private String var = "derived";
#Override
public String getVar() {
return this.var;
}
}
The polymorphic behaviour of the java language works with methods and not member variables: they designed the language to bind member variables at compile time.
In java, this is by design.
Because, the set up of fields to be dynamically resolved would make things to run a bit slower. And in real, there's not any reason of doing so.
Since, you can make your fields in any class private and access them with methods which are dynamically resolved.
So, fields are made to resolved better at compile time instead :)
If I'm only given a field instance from a class, without further knowledge about the class that declares that field, is it possible to get an instance of the declaring (outer) class?
For instance, consider the following class structure.
class A {
static final Tclass t = Tclass.create();
}
Now, in some other function, we are only given t (Tclass instance). Is it possible to use reflection in some way to grab the outer/declaring class (class A) that holds t?
I don't think the statement given t means what you think it means.
If you mean you do something like
someMethod(t);
and you want someMethod to get a reference back to A, you're out of luck. When used in an expression like that, the expression t resolves to a value. That value is a reference to an object. Such a reference is one-way only. someMethod has absolutely no knowledge about the existence of a static variable t.
If you mean you have a Field instance for t, you can simply call Field#getDeclaringClass() to get the declaring class.
Just having a play around with Java reflection and I think I'm getting the hang of it for the most part. I understand from this question/answer that, for the most part, I'm limited to static variables. If I have an instance of the class though, I can access non-static variables, which does make sense, I get that much.
Say I have the following two classes:
public class A
{
private static int _staticInt;
public static void main(String[] args)
{
B instanceOfB = new B();
}
}
public class B
{
private int _nonStaticInt;
public Game() {}
}
I understand how to access _staticInt, that's not an issue.
My understanding is that I can get the Field for _nonStaticInt in the same way (i.e. Field f = B.class.getDeclaredField("_nonStaticInt");). From other research (javadocs, trails, etc) I have gathered that I need an instance of B in order to get the value of _nonStaticInt.
So my question; Since main is static, is it possible to access instanceOfB in order to access the value of _nonStaticInt? I don't think it is possible, but I thought it's always best to consult people that are more knowledgable than myself before giving up on the idea.
Since main is static, is it possible to access instanceOfB in order to access the value of _nonStaticInt?
"No." Local variables (being in a static method or not) cannot be accessed with the Java Reflection API. Reflection only works at the type level, not the byte-code level2.
The stated understanding of the linked question is correct; reflection access of a non-static (instance) field logically requires an instance. That is, the issue then isn't about reflecting on the B type, the issue is about obtaining the B instance (which is assigned to a local variable) to reflect upon.
To do this the B instance has to be "bled" somehow - e.g. assigned to a static field or passed as an argument to a method/constructor from main1 - so that it can be used with reflection later as the object who's instance members are to be accessed.
The cleanest approach would probably be to pass the B instance down through the appropriate context (or "DI"), perhaps with the aide of IoC .. and maybe changing the type to avoid the use of reflection entirely.
1 Another possible way to "bleed" the B instance is to attach a debugger and inspect/use the local variable within the main methods executing frame - but this sounds like trying to swat a fly with a club.
2 Even tooling like BCEL/ASM wouldn't immediately help during the execution of the main method. Rather it would be used to deconstruct the method, add in the required hooks/code to "bleed" or use the instance created, and then construct a modified method to execute.
Yes, you can get the value of _nonStaticInt in that same way:
B instanceOfB = new B();
Field f = B.class.getDeclaredField("_nonStaticInt");
// Because the variable is private you need this:
f.setAccessible(true);
Object content = f.get(instanceOfB);
System.out.println(content);
The value will be 0, that is the default value for an int.
I don't really understand how the class keywords work in some instances.
For example, the get(ClientResponse.class) method takes the ClientResponse.class. How does it use this when it gets it, and what are the advantages over just passing an instance of it?
SomeClass.class
returns a Java Class object. Class is genericized, so the actual type of SomeClass.class will be Class<SomeType> .
There are lots of uses for this object, and you can read the Javadoc for it here: http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html
In ClientResponse.class, class is not a keyword, neither a static field in the class ClientResponse.
The keyword is the one that we use to define a class in Java. e.g.
public class MyClass { } /* class used here is one of the keywords in Java */
The class in ClientResponse.class is a short-cut to the instance of Class<T> that represents the class ClientResponse.
There is another way to get to that instance for which you need an instance of ClientResponse. e.g
ClientResponse obj = new ClientResponse();
Class clazz = obj.getClass();
what are the advantage over just passing a instance of it?
In the above example you can see what would happen in case obj was null (an NPE). Then there would be no way for the method to get the reference to the Class instance for ClientResponse.
The Class class, which is different from the class keyword, is meta-data describing instances. It tells you about the methods, data members, constructors, and other features of the instances that you create by calling new.
For example get(ClientResponse.class) method takes the
ClientResponse.class how does it uses this when it gets it and what
are the advantage over just passing a instance of it?
You can't pass an instance of ClientResponse to this method; it's expecting meta-data about all instances of ClientResponse. If you passed an instance, you'd expect that the method might change the state of that instance. But passing the meta-data about all instances might allow the method to create a new kind of instance (e.g. a dynamic proxy) or do something else that depends on the meta-data about all instances of ClientResponse. See the difference?
A class is a "blueprint" of the object. The instance is a object.
If we have
public class SomeClass {
int a;
SomeClass(int a) {
this.a = a
}
}
We can have an instance of this class
SomeClass c = new SomeClass(10);
c is an instance of the class. It has a integer a with value 10.
The object SomeClass.class represents a Class.
Here SomeClass.class is a object of the type Class which has the information that SomeClass is
a concrete class with
one constructor
with a integer member variable
and lots more other metadata about the class SomeClass. Note that it does not have a value for a.
You should use get(c) incase you are planning to do something with a instance of c like call c.a or other useful functions to manupulate/get data of the instance.
You should use get(SomeClass.class) when the get returns something based on the fact that the argument is some type of class. For example, if this is a method on a Registry class which has a map which retrieves a implementation class based on type of class passed in.
The very most important fact is - you don't need to have an instance to call the method. It's critically useful in situations when you cannot for some reason instantiate a class, e.g. it's abstract, or have only private constructor, or can only be correctly instantiated by some framework, like Spring or JSF.
You can then call get to obtain an object of a requested type without even knowing where it does come from and how it get's created.
Here ClientResponse.class is an instance of Class<ClientResponse>. In general Class object represents type of an object. When you create new instance:
Object obj = new ClientResponse()
you can retrieve the class (type) of that object by calling:
obj.getClass()
So, why would you pass Class objects around? It's less common, but one reason is to allow some method create arbitrary number of instances of a given class:
ClientResponse resp = ClientResponse.newInstance();
There's a lot of ways Class objects can be used. This is used for Reflection. Below is a link that can help you understand more.
http://docs.oracle.com/javase/tutorial/reflect/class/classNew.html
Whenever we compile any Java file, the compiler will embed a public, static, final field named class, of the type java.lang.Class, in the emitted byte code. Since this field is public and static, we can access it using dotted notation along with class name as in your case it is ClientResponse.class.
Is there any way in Java to store a reference to a class? Here's what I want to do:
public class Foo
{
public static void doSomething() {...}
};
SomeClass obj = Foo;
obj.doSomething();
Is there some class "SomeClass" which lets me store a reference to a class, such that I can later use that stored object to call a static member of the original class?
The obvious thing would be class Class:
Class obj = Foo.class;
obj.someMember().doSomething();
but I haven't figured out which of class Class's members might act as "someMember()"... none of them, I think.
Does anyone know if what I'm trying to do is possible in Java?
You can dynamically get a method from a Class object using the getMethod() methods on the class. If a method is static, then the "object" parameter of "invoke" will be null.
For example, the "obj.someMember()" above would be something like this:
obj.getMethod("someMember", null).invoke(null, null);
The extra nulls are because your method requires no parameters. If your method takes parameters, then they will need to be passed in accordingly.
This will throw various checked exceptions, so you'll need to handle those as well.
Once you've invoked the method, it will return an Object. You'll want to cast that to whatever type you're expecting, and then you'll be able to run the "doSomething()" method directly on that.
This is using a trick called reflection, if you'd like to read up more on it. :)
If you are using jdk1.5 or above, annotation will be a choice when you want to get metadata of Class.