I need to call this method : public T unwrap(Class iface) from a class that I can't import.
I'm trying to do this :
Class jbossWrappedSt = Class.forName("org.jboss.jca.adapters.jdbc.jdk6.WrappedPreparedStatementJDK6");
Method metodoUnwrap = jbossWrappedSt.getDeclaredMethod ("unwrap", new Class[]{Class.class});
Object val = metodoUnwrap.invoke (st, new Object[] {PreparedStatement.class});
But fails with a NoSuchMethodException exception:
java.lang.NoSuchMethodException:
org.jboss.jca.adapters.jdbc.jdk6.WrappedPreparedStatementJDK6.unwrap(java.lang.Class)
Class javadoc :
https://repository.jboss.org/nexus/content/unzip/unzip/org/jboss/ironjacamar/jdbc-local/1.0.28.Final/jdbc-local-1.0.28.Final-javadoc.jar-unzip/org/jboss/jca/adapters/jdbc/JBossWrapper.html#unwrap%28java.lang.Class%29
Update: I forgot to say that we are using Java 1.5 (Yeah! I know).
You are asking for a declared method which precludes the possibility to receive an inherited method. So if WrappedPreparedStatementJDK6 inherits the method from JBossWrapper or some other class in the class hierarchy instead of declaring it itself, the lookup will fail. You should use getMethod which will provide you the method regardless of where in the class hierarchy it is defined, provided the method is public which is the case here.
Nevertheless, since it’s defined in standard Java API Wrapper interface, there is no need to use Reflection at all. If the compile-time type of st is not already PreparedStatement, you can simply invoke ((Wrapper)st).unwrap(PreparedStatement.class).
The class in the Javadoc is
org.jboss.jca.adapters.jdbc.JBossWrapper
however the class you are looking at is a different class.
The class you are look at doesn't have an unwrap method.
https://repository.jboss.org/nexus/content/unzip/unzip/org/jboss/ironjacamar/jdbc-local/1.0.28.Final/jdbc-local-1.0.28.Final-javadoc.jar-unzip/org/jboss/jca/adapters/jdbc/jdk6/WrappedPreparedStatementJDK6.html
getDeclaredmethod doesn't follow the inheritance heirarchy to find a method like getMethod does.
As the method is public, I suggest you use getMethod and you won't need to know the class which actually implements the method.
In fact you should be able to call the public method directly, but I assume there is a reason you have to use reflection.
Related
I'm trying to find a solution for a project assignment. Basically I have created a class which is derivative of another abstract class. In it's construction I'm trying to call the supertype constructor with a string and an integer as argument. The issue is that I'm trying to calculate the integer value in an overridden method in the same class. Like so:
super(name, getBaseValue());
This doesn't work because I can't reference the method within the supertype constructor. Maybe I have simply misunderstood the assignment and the UML-diagram. Any ideas how to go about solving this?
getBaseValue() must be static and also use this.getBaseValue (), so that it looks like this:
super(name, this.getBaseValue());
You probably shouldn't do that at all. At the time the constructor runs, the object is not yet created (it's still in the process of being created), and calling a method on it is risky because that method may assume the object is fully created. Even worse, a derived class could also define that method, and then you the parent constructor isn't even done when a child class' method is already called --- chaos.
You can call static methods (which don't require an object instance being created), or you can hard-code any values you want to pass.
See also MET05-J. Ensure that constructors do not call overridable methods in the Secure Java Coding Standard and Sonar Source's warning about this.
I am trying to write an abstract class. In that class I have a method which is supposed to access the actual object for which the method is called.
"this" however will only return the "part of the object" that I write myself (the abstract one).
To specify some more:
If the method I was writing had a parameter of the type of my class, what i want looks like this:
public abstract class MyClass {
public void foo(MyClass invoker) {
...
}
}
The above code would allow me access to the object invoking the method, but it would be tedious to write it like this, since this is supposed to become part of a library I want to supply to others and I cannot know for certain, that the passed argument would in fact be the right object and not some other object of a class derived from MyClass.
Is there a way to invoke something along the lines of getNestingObject() or do I specifically have to give the method a parameter and constantly infer "this" to every call?
Finally, since I am no master in java, a perhaps less obvious question:
Is there a security reason, why the above described concept is flawed? Could someone
with malicious intent abuse that kind of keyword?
I am trying to write an abstract class. In that class I have a method
which is supposed to access the actual object for which the method is
called. "this" however will only return the "part of the object" that
I write myself (the abstract one).
this will return a reference to "the whole" object, not "a part". To proof this, if you cast this reference to a class that is lower in the hierarchy, you can access any property or method of this class using the instance referenced by this.
However, casting the instance referenced by this, would not be a good design practice. Speaking in general terms, you should write a foo method in MyClass with the general behaviour, and override it with the particular behaviour of each classs. If you want to use the foo method of the parent class, you can invoke it using super.
I have a set of similar classes that all implement a function of the form
public static ClassA convertToClassA(Obj A)
public static ClassB convertToClassB(Obj B)
I want to loop through a list of classes and call this function that takes one argument of Obj in each class. How do I do this given each function is named differently?
Thanks for the help.
Class cls = Class.forName("ClassA");
String methodName = "convertTo" + cls.getSimpleName();
Method method = cls.getDeclaredMethod(methodName, new Class[]{Obj.class});
// If the underlying method is static, then the first parameter is ignored. It may be null as illustrated below.
method.invoke(null, your_object);
Create common interface with your method signature and let your invokable classes implement it, later on you can iterate over your objects as over instances of interface and call methods from it so no problem.
HOWEVER I am starting to think you want to call method without knowing it's name AT ALL - the only knowlage of target method is the number and type of arguments. Well that indeed IS impossible via reflection BUT, it will be innacurate if similar methods signatures will be present. Anyway, don't know what are you trying to do, but your project is badly designed from the ground (no interfaces, poor inharitance I guess etc.)
take a look at the reflection package. it provide methods to get back all the methods an instance has provide.
The apache common's BeanUtil (http://commons.apache.org/beanutils) also provide some util method doing similar things.
Suppose that I have this method:
public void callDo(FeelFreeToExtend ext){
ext.do()
}
Where FeelFreeToExtend is this:
public class FeelFreeToExtend {
public void do(){
System.out.println("DO");
}
}
Now I know that someone could override the do method but is there a way that I can explicitly call the do method in the FeelFreeToExtend class? I don't think that this would ever be a great idea however it is still interesting.
No, it is not possible without changing the bytecode/code of all the callers. If you want to always call the FeelFreeToExtend.do() make the method final.
Append the non-access qualifier "final" to the method (make the method final), this will stop the method from being overridden and hence this version of the method will be called always from any of the subclasses.
Secondly, if you just want to access a super class method from a derived class even if the super class method has been overridden then just call the method by appending "super." before the method call.For eg. to call the method "display" of a super class from a subclass, use super.display(). (This assumes that you are the one coding the sub class)
Actually what Peter says is not completely correct: in fact it is possible to execute an overridden method using JNI (http://java.sun.com/docs/books/jni/html/fldmeth.html#26109). In JNI there are method called CallNonvirtual<Type>Method allowing exactly that.
Application servers or frameworks could be shipped with a small JNI utility to allow this kind of features...
Without JNI I don't think this is possible.
I am storing a list of classes through (Classname.class) and would like to instantiate one? Is this possible?
newInstance seems to the method I am after but it doesn't support a constructor?
You can use Class.getConstructors (or Class.getConstructor) to get a list of available constructors, and invoke any of them with Constructor.newInstance, which does accept parameters.
Just to add one point I see missing:
You can invoke newInstance directly on the Class object if it has a public null constructor. (Null constructor is the constructor with no arguments.)
Otherwise, you can find constructors via Class.getConstructors() as others have said.
The Java tutorial on reflection covers this well. But yeah, basically Class.getConstructors, then Constructor.newInstance is where it's at.
Java is designed so you can never "trick" it as long as you use the java.lang/java. classes or other standard libraries. One of the most important things of OOP is that objects should be in a defined state, thus you can be safe that the constructor is always run. Even if you're using some strange-looking reflection libraries to get your work done.
So, using Class.forName("me.Test").newInstance(); (or similar) will under-the-hood invoke the Test() constructor for you.
If you want to invoke another constructor the code is something like:
Test test = (Test)Class.forName("Test").getConstructor(String.class).newInstance("Hello World");
Here the getConstructor asks what the constructor looks like (it wants a string) and then you call it with a string.
You cannot construct new classes this way.
If you have the name of a class you can use Class.forName(className) to load/reference a class.
If you have the byte code for a class you want to create you can have a class loader load the byte code and give you the class. This is likely to be more advanced than you intended.
If you have a list of Class objects obtained through class literals, you might as well statically reference the constructors rather than slipping into reflection evilness.