I am attempting to call a custom class and method on my Application start-up to perform dev testing. I have stored the setting for my test class and method in my SettingsClass as shown below.
public class SettingsClass {
public static final boolean BOOT_TEST = true;
public static final String BOOT_CLASS = "MyClass";
public static final String BOOT_METHOD = "MyMethod";
}
My Main Class.
public class MainClass {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
if(SettingsClass.BOOT_TEST) {
Method method = getDeclaredMethodClass(SettingsClass.BOOT_CLASS).getDeclaredMethod(SettingsClass.BOOT_METHOD);
method.invoke();
System.exit(1);
}
}
Is it possible to perform the above action?
Any help would be appreciated.
You need both a reference to the Class type and an instance of the class (unless the method you want to invoke is static). In your pseudo code you have the correct idea, all you need to do is a quick review of the javadoc for java.lang.Class and java.lang.reflect.Method
public class SettingsClass {
public static final boolean BOOT_TEST = true;
public static final String BOOT_CLASS = "MyClass";
public static final String BOOT_METHOD = "doMain";
}
public class MyClass {
public static void doMain() {
}
}
public class MainClass {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
if(SettingsClass.BOOT_TEST) {
Class<?> clazz = Class.forName(SettingsClass.BOOT_CLASS);
Method m = clazz.getMethod(SettingsClass.BOOT_METHOD);
m.invoke(null);
System.exit(1);
}
}
for .invoke() you need an object that is an instance of your class.
if your class has an public default consturctor you should be able to do something like this
// load your class
Class<?> clazz = Class.forName("full.package.and.class.name");
// get the method
Method method = clazz.getDeclaredMethod("methodName");
// create an instance of your class
Object object = clazz.newInstance();
// call the method in context of object
method.invoke(object);
You can refer to Java reflection (Method Invocation)
http://docs.oracle.com/javase/tutorial/reflect/member/methodInvocation.html
you can find methods through
Class<?> c = Class.forName("nameClass");
Object t = c.newInstance();
Method[] allMethods = c.getDeclaredMethods();
and you can call through
m.setAccessible(true);
Object o = m.invoke(t, .... )
Yes, it is. The following code will execute the method someMethod in the MainClass.
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MainClass {
public static final boolean BOOT_TEST = true;
public static final String BOOT_CLASS = "MainClass";
public static final String BOOT_METHOD = "someMethod";
public static void main(String[] args) throws InstantiationException,
IllegalAccessException, ClassNotFoundException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
if (MainClass.BOOT_TEST) {
Class bootClass = Class.forName(BOOT_CLASS);
Method bootMethod = bootClass.getDeclaredMethod(BOOT_METHOD, null);
bootMethod.invoke(null, null);
}
}
public static void someMethod() {
System.out.println("Some method executing...");
}
}
What you need to do is get the class object for the class whose method you wish to execute dynamically by using the static method Class.forName(String) passing in the class's name. subsequently you can request the method you wish to execute using the getDeclaredMethod(String, Class<?>...) passing in the method's name and parameter types. Following that you can call invoke(Object, Object...) on the method with two null arguments (execute the method on no instance of the class (static execution) without any parameters).
Related
Need to call a private method foo() of the class Inner.Private, where Private is an inner private class from the main method of the main class.
The code is something like this:
public class MainClass {
public static void main(String[] args) throws Exception {
// Need to invoke foo() from here
}
static class Inner {
private class Private {
private String foo() {
return "someString";
}
}
}
}
I was trying to get this using Java Reflection, but I am facing issues from this approach.
My attempt to invoke the foo() is:
Inner innerClassObject = new Inner();
Method method = Inner.Private.class.getDeclaredMethod("foo");
method.setAccessible(true);
method.invoke(innerClassObject);
But this gives a NoSuchMethodException:
Exception in thread "main" java.lang.NoSuchMethodException:
default.MainClass$Inner$Private.foo()
at java.lang.Class.getDeclaredMethod(Unknown Source)
I am stuck at this point, is this achievable by Java Reflection, or any other way?
Ummm... why not simply new Inner().new Private().foo()?
Why are you doing this
Inner.Private.class
Instead of
innerClassObject.getClass()
For e.x:
public class Test {
private int foo(){
System.out.println("Test");
return 1;
}
public static void main(String [] args) throws InterruptedException,
NoSuchMethodException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException
{
Test innerClassObject = new Test();
Method method =
innerClassObject.getClass().getDeclaredMethod("foo",null);
method.setAccessible(true);
method.invoke(innerClassObject);
}
}
Why waste an instantiation just to call a method as was described? You will inevitably want to save various instances for latter use as the classes develop.
public class MainClass {
public static void main(String[] args) throws Exception {
// Need to invoke foo() from here
Inner inner = new Inner();
Inner.Private pvt = inner.new Private();
System.out.println(pvt.foo());
}
static class Inner {
private class Private {
private String foo() {
return "someString";
}
}
}
}
Prints
someString
I'm testing with Java reflection and trying to apply overloaded method to parameters according to their type..
However, I have NoSuchMethodException even though the method I tried to get is public. This exception still appears when I used getDeclaredMethod.
Here's the main program
public class Test {
public static void main(Object... inputs){
InputManipulation test = new InputManipulation();
for (Object input: inputs){
Class ownerClass = test.getClass();
Class inputClass = input.getClass();
Method method = ownerClass.getDeclaredMethod("add", inputClass);
method.invoke(test, "Testing reflection");
}
}
}
And here's the self-defined InputManipulation class
public class InputManipulation {
Integer total;
public InputManipulation(){this.total = 0;}
public void add(Integer num){this.total += num;}
public void add(String str){System.out.println(str);}
}
Thanks in advance!
I now changed the Test class as follows.. but the problem still exists.
public class Test {
public static void main(String[] args){
Test testExample = new Test();
testExample.testMethod("String1", 1, "String2");
}
public void testMethod(Object... inputs){
InputManipulation test = new InputManipulation();
for (Object input: inputs){
Class ownerClass = test.getClass();
Class inputClass = input.getClass();
Method method = ownerClass.getDeclaredMethod("add", inputClass);
method.invoke(test, "Testing reflection");
}
}
}
I also tried putting the inputClass into an array of Class, as suggested by another post, but it didn't help..
There seems to be a few issues with the initial code you provided and as others have suggested using an IDE would have pointed some of the issues out pretty quickly. However, I have taken your update and fixed the code to call the proper method in the loop you provided of input types.
First change your InputManipulation class like so:
public class InputManipulation {
Integer total;
public InputManipulation() {
this.total = 0;
}
public void add(Integer num) {
this.total += num;
System.out.println(this.total);
}
public void add(String str) {
System.out.println(str);
}
}
Now alter your Test class like so:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) {
Test testExample = new Test();
testExample.testMethod("String1", 1, "String2");
}
public void testMethod(Object... inputs){
InputManipulation test = new InputManipulation();
for (Object input: inputs){
Class<? extends Object> ownerClass = test.getClass();
Class<? extends Object> inputClass = input.getClass();
//Method method; //not needed
try {
ownerClass.getDeclaredMethod("add", inputClass).invoke(test, input);
} catch (NoSuchMethodException | SecurityException |
IllegalAccessException | IllegalArgumentException |
InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
I used these readings to help guide my answer, but altered the way I invoked the method:
http://tutorials.jenkov.com/java-reflection/methods.html
public class Test {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Test testExample = new Test();
testExample.testMethod("String1", 1, "String2");
}
public void testMethod(Object... inputs) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
InputManipulation test = new InputManipulation();
for (Object input: inputs){
Class ownerClass = test.getClass();
Class inputClass = input.getClass();
Method method = ownerClass.getDeclaredMethod("add", inputClass);
method.invoke(test, input);
}
}
}
Your problem was caused by this method.invoke(test, "Testing reflection");
You iterate through 2 types of arguments and depends of this argument you invoke method 'add'. When you tried to invoke method with argument Integer you pass to method String parameter that causes error
I want do something like this :
public myMethod(Object expectedValue) {
java.lang.reflect.Method method = new Method(expectedValue);
System.out.println(method.getName());
}
How do I get a method reference from the getter itself without introducing string coupling (specifying the getter name) ?
Don't know if I understood your question right, but below you'll find the code who you can invoke a getter from an object using reflection. Afaik, there is no way to get a method without refering to its name.
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Foo foo = new Foo();
foo.setBla("i am bla");
Method blaGetter = Foo.class.getMethod("getBla");
System.err.println(blaGetter.invoke(foo));
}
private static class Foo {
private String bla;
public String getBla() {
return bla;
}
public void setBla(String bla) {
this.bla = bla;
}
}
In these two classes I have passed an object of TestClassTwo in the getName method of TestClass from main method now I would like to call getTwoName method using an object obj. Can some one please help me with that. thanks
// Below is the code
// class1
package Test;
public class TestClassTwo {
public static String getTwoName()
{
return "2nd";
}
}
// class2
package Test;
public class TestClass {
public void getName(Object obj) throws InstantiationException, IllegalAccessException, ClassNotFoundException
{
// call getTwoName method of TestClassTwo using obj object
}
public static void main(String args[]) throws InstantiationException, IllegalAccessException, ClassNotFoundException
{
TestClass tc=new TestClass();
tc.getName(new TestClassTwo());
}
}
cast the Object (the super class) to TestClassTwo (the sub class):
String name = ((TestClassTwo) obj).getTwoName();
or:
TestClassTwo temp = (TestClassTwo) obj
String name = temp.getTwoName();
Note that using an instance to call static method is useless. Instead, use the class name to call the static method:
String name = TestClassTwo.getTwoName();
As the others have said, if you intend to access the method statically, you do not need an instance, and therefore you do not need a parameter in TestClass#getName at all. If you do want it to be an instance method, however, you can do one of three things:
1) Take in the type TestClassTwo in TestClass#getName:
public class TestClass {
public void getName(TestClassTwo obj) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
String name = obj.getTwoName();
// Do something with 'name'
}
public static void main(String args[]) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
TestClass tc=new TestClass();
tc.getName(new TestClassTwo());
}
}
2) Cast the object to an instance of TestClassTwo, checking the type:
public class TestClass {
public void getName(Object obj) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
if (obj instanceof TestClassTwo) {
TestClassTwo two = (TestClassTwo) obj;
String name = two.getTwoName();
// Do something with 'name'
} else {
// Handle failure accordingly (throw an exception, log an error, do nothing, etc.)
}
}
public static void main(String args[]) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
TestClass tc=new TestClass();
tc.getName(new TestClassTwo());
}
}
3) If you want to allow other classes to have a getTwoName() function, define an interface and take an instance of that interface as a parameter to TestClass#getName:
public interface HasTwoName {
public String getTwoName();
}
public class TestClassTwo implements HasTwoName {
#Override
public String getTwoName() {
return "2nd";
}
}
public class TestClass {
public void getName(HasTwoName obj) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
String name = two.getTwoName();
// Do something with 'name'
}
public static void main(String args[]) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
TestClass tc=new TestClass();
tc.getName(new TestClassTwo());
}
}
Why? You don't need to use any object, as the method is static. Using an object to call this method is futile. Just write TestClassTwo.getTwoName().
[I strongly suspect there is something wrong with your question.]
If you really need to access a static method of an unknown class via an object of that class, this is how you do it:
String twoName = obj.getClass().getMethod("getTwoName").invoke(null);
I used the following code to identify the number of functions in a class. Similar way can any one help me to identify the number of functions in a java program. In my program i gave input file as a class. Guide me with the code to give input as a java program and to find the number of declared functions in it.
import java.lang.reflect.*;
import java.io.*;
import java.lang.String.*;
public class Method1 {
private int f1(
Object p, int x) throws NullPointerException
{
if (p == null)
throw new NullPointerException();
return x;
}
public static void main(String args[])throws Exception
{
int Mcount=0,MthdLen=0;
try {
Class cls = Class.forName("Madhu");
int a;
Method methlist[]= cls.getDeclaredMethods();
for (int i = 0; i < methlist.length;i++)
{
Method m = methlist[i];
Mcount = Mcount + 1;
MthdLen=MthdLen+(m.getName().length());
}
}
catch (Throwable e) {
System.err.println(e);
}
System.out.println("Length = " + MthdLen);
System.out.println("Mcount = " + Mcount);
}
}
First of all,
Class cls = Class.forName("Madhu");
Requires the fully qualified name of the desired class. e.g Class.forName("java.lang.Thread")'.
Secondly,
Method methlist[]= cls.getDeclaredMethods();
returns public, protected, private and default method of that specific class only (it excludes inherited methods).
Thirdly,
MthdLen=MthdLen+(m.getName().length());
Sums up the string length of the method name. What do you need this for? You could simply do a count as follows:
int MCount = cls.getDeclaredMethods().length; //If the "getDeclaredMethods()` doesn't return a null.
Finally, if you need to get all inherited public & protected methods of that class, you would do
Class<?> class2 = cls.getSuperClass();
//Get all methods using
Method[] methods2 = class2.getDeclaredMethods();
//Iterate through methods2 and retrieve all public, protected methods and add it to MCount.
Hope this helps.
Java doesn't have any functions so the answer is 0. ;)
If you are looking for the number of methods, you have to ask yourself, do you want to
include inherited methods.
count overriden methods once ore multiple times.
include all the methods in Object or not.
e.g.
public class Main {
static class A {
public String toString() {
return super.toString();
}
}
static class B extends A {
public String toString() {
return super.toString();
}
}
public static void main(String args[]) {
for(Class clazz = B.class;clazz != null;clazz = clazz.getSuperclass()) {
for(Method m: clazz.getDeclaredMethods())
System.out.println(m);
}
}
}
prints
public java.lang.String Main$B.toString()
public java.lang.String Main$A.toString()
protected void java.lang.Object.finalize() throws java.lang.Throwable
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
protected native java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException
private static native void java.lang.Object.registerNatives()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
In JDK6+, you could compile the file at runtime using JavaCompiler, and use your old code to find the number of methods.
EDIT:
Bonus: Replace your code with
System.out.println("Total number of methods: " +
java.beans.Introspector.getBeanInfo( //your class name here
).getMethodDescriptors().length);
i use this code to find out count of method in a class inside of another class.
public class test1 {
public static void main(String[] args)
//if use in class
//Method[] s = getClass.getDeclaredMethods();
Method[] s = SmokeTestTests.class.getDeclaredMethods();
int methodCounter = 0;
for (Method method :
s) {
++methodCounter;
}
System.out.println(methodCounter);
}