I understand that the following can be done .
User user = new User();
user.setUsername("a");
user.setPassword("abc");
Class c = user.getClass();
However I have a situation in which I have to extract the instance information from the variable "c"
Is it even possible ? . We do have a c.newInstance() method but that would create a new instance of the object User. I need to access the existing instance of the User , which was responsible for creating the "c" variable in the first place .
Thanks
-----------EDIT-----------
Looking at the comments I understood that my concept of getClass was flawed . What I want to achieve is that I need a method which would iterate over an object's getters . So what would be the signature of such ?
I was thinking on the lines of
public static <T> List<NameValuePair> entityConvert1(Class<T> entity)
however as per all the comments , I understand passing the Class wont send in any instance specific information in the method .
I need a torch here .
Update:
It seems like, you just want to get the getter methods from your class, and invoke it to get the value for a particular instance.
You can get all the getters using Introspector. Write a generic method, taking 2 arguments - Class<T>, and T types:
public static <T> void executeGetters(Class<T> clazz, T instance) throws Exception {
BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
for(PropertyDescriptor propertyDescriptor: beanInfo.getPropertyDescriptors()){
// Get Method instance used for reading this property
Method method = propertyDescriptor.getReadMethod();
// Invoke this method on 'instance'.
System.out.println(method.invoke(instance));
}
}
Now, invoke this method as:
executeGetters(User.class, user);
This will print the value of all the properties for user instance. Note, if there is a getter method missing for the User class, this Method instance will be null, and you might get a NPE. You need to check for that.
I need to access the existing instance of the User , which was responsible for creating the "c" variable in the first place
Can't be done because there is no link between the getClass() method's result and c. The problem is that the Class c represents an instance of the type of c not the particular instance which is user. Class itself is a representation of the bytecode file loaded by the JVM and what it exposes so you can do reflection operations. It's not even directly analogous to the actual User class represented by the bytecode. It's more low level than what you're thinking.
Related
i need to call a function - (getters and setters of a property), but my problem is, the name of the property is generated at runtime (name of some variable + number).
Is it possible to manipulate the bytecode via javassist or gclib so that the function calls are directed to some proxy object/function, and there the real method name and the number extracted from the called function name, so that i can call the function afterwards (with the number as parameter)?
I tried the following, but it didnt work:
MethodHandler handler = new MethodHandler() {
#Override
public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) {
String realMethodName=thisMethod.substring(0,5);
Integer param=Integer.parseInt(thisMethod.substring(5));
Method m = self.getClass().getMethod(realMethodName);
m.invoke(self,param);
return null;
}
};
I think this might be one of the few scenarios where using Java reflection Proxy objects might come in handy.
You could define some interface, but delegate the method to the (dynamic) invocation handler which would then call those "getter/setter" methods.
Side note: when implementing such an invocation handler you have to understand that ANY method call on the corresponding object will trigger its "invoke" method; event when you call toString or equals or whatever else is inherited from Object.
EDIT: and one more (different) thought: are you sure you need to create dynamic method names at all? If you have some numeric (or string based) key - what not using a Map for example?
Like
Map<WhateverKeyType,YourPropertyClass>
that would be much more "normal java" way of handling your problem (instead of thinking about reflection or byte code manipulation).
If you wanted to implement something similar but could think of using another library than javassist, consider using Byte Buddy (which I wrote, for disclosure).
Considering, you have an interface
interface Foo { Object getProperty() }
that you wanted to implement to access a property of the bean
class Bar { Object getAbc123() { ... } }
Then using Byte Buddy, you could implement a class
Foo accessor = new ByteBuddy()
.subclass(Foo.class)
.method(named("getProperty"))
.intercept(MethodCall.invoke(Bar.class.getDeclaredMethod("getAbc123"))
.on(new Bar()))
.make()
.load(Foo.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded()
.newInstance();
of the interface that redirects the invocation of getProperty to the method of your choosing. With a little bit of customization, you can surely create a more generic solution.
Why can't I get the "get" method of an ArrayList and invoke it?
I am using reflection to modify within my nested classes. One of my classes has a list of classes so I wanted to be able to use the same logic to get and invoke the get method.
simplified, the line that fails is
ArrayList.class.getClass().getMethod("get")
and it fails, giving me a NoSuchMethodException.
I understand that I could use aList.get() but that's not the point, I need to use reflection since this is in a deeply nested class.
TL;DR
How can I get the "get" method of an array list?
Note that Class#getMethod() has two parameters: a String and an vararg of Class objects. The former is
the list of parameters
that the method declares.
You need to use
ArrayList.class.getMethod("get", int.class);
since the ArrayList#get(int) method has an int parameter.
I initially missed the whole
ArrayList.class.getClass().getMethod("get")
^ ^
| |----------------------------- gets Class<Class>
|----------------------------------- gets Class<ArrayList>
The .class already gets the Class instance for ArrayList. Calling getClass on that will return the Class instance for class Class. You don't want that.
Method methods = ArrayList.class.getMethod("get", int.class);
You do not need to call getClass() method again after .class because when you write .class after a class name, it references the Class object that represents the given class.
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.
If I do this in Java to call a method name from a class dynamically, it works.
MainApp app = new MainApp();
Method meth = app.getClass().getMethod("myMethod", MyParameterType.class);
//call method
meth.invoke(app, new MyParameterType("hello"));
But this worked because I know the constructor in the invoke method. But if I were to pass the Method object as a parameter to some other classes, and I don't know who is the constructor, I cannot invoke the method any more. Even if I know, I may not want to create a different object to just make a call to the method. For eg:
//This is in the class call MainApp.java.
//There is a method in MainApp.java that looks this way: myMethod(MyParameterType param);
MainApp app = new MainApp();
OtherClass myClass = new OtherClass();
Method meth = app.getClass().getMethod("myMethod", MyParameterType.class);
myClass.callMe(meth);
//Inside OtherClass.java
public void callMe(Method meth) {
//call method
meth.invoke(########, new MyParameterType("hello"));
}
In this case, what should I put for the ######## parameter? Within the context of OtherClass.java, the base constructor object wouldn't be known. And why would I need if since meth is already a Method type that I just call like a function?
Thanks
Assuming it's an instance method, you've got to have an instance to call the method on, just like anything else. How you get hold of that instance will depend on what you're trying to do; you could pass in a Constructor, or a reference to an existing object, or some interface which will create the instance when you ask it to... we can't really give you any advice on which approach is the most suitable without knowing what you're trying to do.
If it's a static method, you can pass null for the first argument.
What it seems you are looking for or thinking about is the concept of `lambda functions``. Those can be called in isolation.
A Method type is not a standalone method, but more like a 'path' into an object. Compare this with a relative URL like /subscribe.html. Out of context this is pretty useless, but when bundled with a site like www.example.com it makes sense.
As such, Method can only be used in combination with an instance. (edit: as John mentioned, unless it's a static method of course which do not need instances)
If you can safely invoke a method without providing an instance, it should be a static method, in which case any instance provided is ignored, you can give it null.
If you have to provide an instance of the object, there is no way around this.
If the developer who write the method has labelled it non-static incorrectly, I suggest you discuss with them why they did it.
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.