Access class defined in method in Java - java

In Java, is it possible to access class defined in method by some means (reflections or so)? And How?
For example, i want to create instance of InnerClass in example below:
class Example {
public void outerMethod() {
class InnerClass {
double d = 0;
}
}
public void testMethod() {
outerMethod::InnerClass instance = new outerMethod::InnerClass();
}
}
Thanks for answers.

Technically it is possible.
Practically this is a kind of a hack and you should avoid such practice in the production code.
Example:
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
class Example {
public void outerMethod() {
class InnerClass {
private double d = 7.62;
#Override
public String toString() {
return String.format("[%s] d = %f", this.getClass().getName(), d);
}
}
}
public void testMethod() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
final Class<?> clazz = Class.forName("Example$1InnerClass");
final Constructor<?> constructor = clazz.getDeclaredConstructor(Example.class);
constructor.setAccessible(true);
final Object instance = constructor.newInstance(this);
System.out.println(instance);
}
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
Example instance = new Example();
instance.testMethod();
}
}
Here we first get Class<?> for our local class by their name.
The local class name generation rules is a compiler implementation detail and may vary. AFAIK javac and ECJ use different approaches.
Then we get constructor of our class of interest via reflection.
Since class does not define constructor explicitly compiler generate it automacically and this constructor is not public. So we use getDeclaredConstructor() method here.
Since this class is not static (local classes cannot be defined static) the first and the only parameter of constructor is outer class reference. Example in our case.
After that we creating instance of a class by calling constructor.newInstance(this)
this is passed as a parameter to the constructor. See note above about constructor parameters.
Finally, we print just created object implicitly invoking InnerClass::toString()

No, that is not possible. Names declared inside a method can only be referenced inside the method itself. Local classes (which your case is an example) are defined in section 14.3 of the Java 8 Language Specification.
https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-Block.

Related

How to Dynamically call a method of a class if class name is passed as string

I want to create dynamic object so that I call the respective method of the class. All classes and interface is in different file but under the same folder
Given:
interface Method
{
public void display();
}
class Car implements Method
{
public void display()
{
System.out.print("Car method");
}
}
class Honda implements Method
{
public void display()
{
System.out.print("Honda method");
}
}
public class Main {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
String className = "Car";
Class cls = Class.forName(className);
Method method = (Method) cls.getConstructor().newInstance();
method.display();
}
}
Now if pass Honda in the string then I want to string method to get called but if I pass Car in string then I want to get Car method as an output but after compilation this method is not getting called. There is no error but no expected output as well. How to get the desired output. Please help.
You can invoke the desired method.
Method method = cls.getMethod("display");
method.invoke(parameters);
If I am allowed to update above code, it would be something like below,
interface Car
{
public void display();
}
class Honda implements Car
{
public void display()
{
System.out.print("Car method");
}
}
public class Main {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
String className = "Car";
Class cls = Class.forName(className);
Honda honda = (Honda)cls.newInstance()
honda.display();
}
}
Hopefully this will clear the things about the Method class I mentioned in above answer.
The method class.newInstance() has been deprecated. So you should use
Class<?> clazz = Class.forName(className);
Constructor<?> ctor = clazz.getConstructor(String.class).newInstance();
Object object = ctor.newInstance(ctorArgument);
SN: In this case I assumed the constructor had only one String parameter value. the getConstructor method must be called passing all the class types (correctly ordered) that the desired constructor has.
While with newInstance you need to pass the actual constrctor's args' values
At this point you have to get the method with getMethod() which requires both the method name and all the arguments' types. To actually invoke the method, you pass the instance of the object of which to call the method (in this case our object and passing the actual parameters' values to call it with
clazz.getMethod("methodName", String.class, String.class).invoke(object, "parameter1", "parameter2");
EDIT: The OP updated the question implementing a common interface by both classes. In this case you can actually call the method that you KNOW will have every class implementing that interface. This way you don't have to use any reflections magic except for creating the new instance of the object itself
With the common interface it'd be
Method method = (Method) Class.forName(className).getConstructor().newInstance();
method.display();
The last line will call the display method of the object instance that is implementing the interface

How can you declare that all subclasses of an abstract class will implement main?

I have an abstract class called Trader which acts like a client with a server (StockMarket) and I would like to declare in the Trader class that all classes that inherit from it will need to implement a main entry point so that they can be run.
The problem is that if I write:
public static abstract void main(String[] args) throws Exception;
it gives an error that only visibility modifiers are allowed. But if I remove the static modifier then it does not work as a main entry point allowing it to be run.
So how to declare all subclasses of an abstract class must implement a main method?
You can't.
What I would do instead is declare an abstract, non-static method in Trader:
public abstract void run(String[] args) throws Exception;
And then declare a separate main class that would instantiate an instance, and call the run method:
class RunTrader {
private static final String DEFAULT_CLASS = "...";
public static void main(String[] args) {
try {
String className = System.getProperty("main-trader-class", DEFAULT_CLASS);
Class<Trader> traderClass = (Class<Trader>)Class.forName(className);
Trader trader = traderClass.newInstance();
trader.run(args);
} catch (Exception e) {
// handle the exception
}
}
}
Lets start with the meaning of
public static void main (String[] args)...
static
means that this method does require an instance of the class (containing this method). Java virtual machine (JVM) states this as a requirement for the entry point of a program, reason being that the class may have multiple constructors or no default constructor and there is no way for JVM to know how to create object of the class.
public
allows the method to be accessible outside the package (and class obviously), so JVM is free to invoke this method.
main
is the name of the method that JVM looks for in the class, since there could be multiple public static methods.
void
returns nothing. This is the part of the signature that JVM looks for as entry point.
Now lets answer your question in light of this information. Polymorphism is relevant to OOP concept of inheritance and interface implementation, and it irrelevant to static methods.
So the only choice you have is to choose 1 'public static void main' method as the entry point based on the 'args', call other public static methods. However, other methods need not have the same signature.
Static methods cannot be abstract.
Static members data are same for all the objects and derived classes.
Static members can't be overridden by derived class.
Since abstract method need to be defined in derived class it can't be static.
Remove static and try.
static method does not supports polymorphism, so you can't declare it as abstract. but you can declaring an abstract class with abstract methods that #MauricePerry has been proposed. I will come up with how to get the Main class?
you can extract the Main class name from the system property sun.java.command.
truncate the args from the command.
second, truncate the IDE Main class name if present.
here is my implementation you can using:
public abstract class Trader {
protected abstract void run(String... args);
public static void main(String[] args) throws Exception {
runAs(getMainClass(args)).run(args);
}
private static Trader runAs(Class<?> mainClass)
throws IllegalAccessException, InstantiationException {
checking(!Modifier.isAbstract(mainClass.getModifiers())
, () -> "abstract class can't be run: " + mainClass);
checking(Trader.class.isAssignableFrom(mainClass)
, () -> "class is not a " + Trader.class
+ " can't be run: " + mainClass);
return Trader.class.cast(mainClass.newInstance());
}
private static void checking(boolean condition, Supplier<String> message) {
if (!condition) {
throw new IllegalArgumentException(message.get());
}
}
private static Class<?> getMainClass(String... args)
throws ClassNotFoundException {
String command = commandWithoutArgs(args);
String[] classes = command.split("\\s+");
return Class.forName(classes[ classes.length - 1]);
}
private static String commandWithoutArgs(String[] args) {
String command = System.getProperty("sun.java.command");
return command.substring(0, command.length() - argsLength(args)).trim();
}
private static int argsLength(String[] args) {
if (args.length == 0) {
return 0;
}
return Stream.of(args).collect(Collectors.joining(" ")).length() + 1;
}
}
Example
public class Application extends Trader {
#Override
protected void run(String... args) {
System.out.println("Application");
}
}
run the Application using command java Application or run it in IDE.
To run a program JVM find main method like
public static void main(String[] args)
abstract is not used with main method

getConstructor with no parameters

I can't seem to use getConstructor for constructors with no parameters.
I keep getting the following exception:
java.lang.NoSuchMethodException: classname.<init>()
Here is the code:
interface InfoInterface {
String getClassName();
String getMethodName();
String getArgument();
}
class asa implements InfoInterface {
#Override
public String getClassName() {
return ("jeden");
}
#Override
public String getMethodName() {
return ("metoda");
}
#Override
public String getArgument() {
return ("krzyk");
}
}
class Jeden {
Jeden() {
System.out.println("konstruktor");
}
public void Metoda(String s) {
System.out.println(s);
}
}
class Start {
public static void main(String[] argv) {
if (argv.length == 0) {
System.err.println("Uzycie programu: java Start nazwa_klasy nazwa_klasy2...");
return;
}
try {
for (int x = 0; x < argv.length; x++) {
Class<?> c = Class.forName(argv[x]);
InfoInterface d = (InfoInterface) c.newInstance();
String klasa = d.getClassName();
String metoda = d.getMethodName();
String argument = d.getArgument();
Class<?> o = Class.forName(klasa);
// o.newInstance();
Constructor<?> oCon = o.getConstructor();
System.out.println("ASD");
Class<?> p = (Class<?>) oCon.newInstance();
}
} catch (Exception e) {
System.out.println(e);
}
}
}
o.newInstance(); prints "konstruktor" without problems.
The problem is clear when you read the javadoc of .getConstructor():
Returns a Constructor object that reflects the specified public constructor of the class represented by this Class object.
Emphasis mine.
In your code, the constructor is not public!
Example:
// Note: class is NOT public -- its default constructor won't be either
final class Test
{
public static void main(final String... args)
throws NoSuchMethodException
{
// throws NoSuchMethodException
Test.class.getConstructor();
}
}
Obligatory link to an SO answer which also gives the JLS reference. In particular, note that the default constructor has the same access modifier as the class.
It seems as if your class provides a constructor that is NOT a default constructor. The call to getConstructor() without parameters requires the class to have a default constructor. The following test illustrates this.
import org.junit.Test;
public class ConstructorTest {
public static class ClassWithParameterizedConstructor {
public ClassWithParameterizedConstructor(final String param) {
// A parameterized constructor, no default constructor exists
}
}
#Test
public void testFoo() throws NoSuchMethodException {
// Parameterized constructor lookup works fine
ClassWithParameterizedConstructor.class.getConstructor(String.class);
// This doesn't work since there is no default constructor
ClassWithParameterizedConstructor.class.getConstructor();
}
}
So, a possible solution is to either change the call to getConstructor() to include the correct type or to provide a default constructor on the object itself (but why would you do that?).
Read this: http://docs.oracle.com/javase/tutorial/reflect/member/ctorInstance.html
It seems that both classes Class and Constructor have the method newInstance the difference is that in the Class class you can only call newInstance with no arguments, so the called constructor must have an no arguments (this also brings a problem when you have more that one constructor).
The methoe newInstance in the Constructor class allows you to call the constructor with arguments also, notice that you can also use the method getConstructors instead of getConstructor that returns you all the class constructors and allows you to call the constructor method you want.
In this case, since you only have one constructor only and with no arguments, Class.newInstance works fine. To use the getConstructor to have the same result you'll need to add in the end oCon.newInstance();
You can use getDeclaredConstructors() which returns an array of Constructor objects reflecting all the constructors declared by the class represented by this Class object
class SomeClass{
{
System.out.println("I'am here!");
}
}
public class Main {
public static void main(String[] args) throws Exception{
System.out.println(Arrays.toString(SomeClass.class.getDeclaredConstructors()));
// returns public, protected, default (package) access, and private constructors
// System.out.println(SomeClass.class.getConstructor());
// in that case you got:
// NoSuchMethodException: reflection.SomeClass.<init>()
// because SomeClass don't have public constructor
for (Constructor constructor : SomeClass.class.getDeclaredConstructors()){
constructor.newInstance();
}
}
}
And if you have private constructor like this:
class SomeClass{
private SomeClass(String val){
System.out.println(val);
}
}
You have to set accessible for constructor:
constructor.setAccessible(true);
And get something like this:
class SomeClass{
private SomeClass(String val){
System.out.println(val);
}
}
public class Main {
public static void main(String[] args) throws Exception{
for (Constructor constructor : SomeClass.class.getDeclaredConstructors()){
// constructor.newInstance("some arg"); // java.lang.IllegalAccessException
constructor.setAccessible(true);
constructor.newInstance("some arg");
}
}
}
Note: if your class declared as private his default constructor must be private too.
And be careful with nonstatic-inner classes, which receives an outer class instance
In this (somewhat convoluted) scenario, it's actually possible to get hold of the (non-public) constructor by replacing:
Constructor<?> oCon = o.getConstructor();
with
Constructor<?> oCon = o.getDeclaredConstructor();
The "default" visibility of the Jeden class (and its constructor) makes it accessible to the Start class, since it's defined in the same package.

How can I access a private constructor of a class?

I am a Java developer. In an interview I was asked a question about private constructors:
Can you access a private constructor of a class and instantiate it?
I answered 'No' but was wrong.
Can you explain why I was wrong and give an example of instantiating an object with a private constructor?
One way to bypass the restriction is to use reflections:
import java.lang.reflect.Constructor;
public class Example {
public static void main(final String[] args) throws Exception {
Constructor<Foo> constructor = Foo.class.getDeclaredConstructor();
constructor.setAccessible(true);
Foo foo = constructor.newInstance();
System.out.println(foo);
}
}
class Foo {
private Foo() {
// private!
}
#Override
public String toString() {
return "I'm a Foo and I'm alright!";
}
}
You can access it within the class itself (e.g. in a public static factory method)
If it's a nested class, you can access it from the enclosing class
Subject to appropriate permissions, you can access it with reflection
It's not really clear if any of these apply though - can you give more information?
This can be achieved using reflection.
Consider for a class Test, with a private constructor:
Constructor<?> constructor = Test.class.getDeclaredConstructor(Context.class, String[].class);
Assert.assertTrue(Modifier.isPrivate(constructor.getModifiers()));
constructor.setAccessible(true);
Object instance = constructor.newInstance(context, (Object)new String[0]);
The very first question that is asked regarding Private Constructors in Interviews is,
Can we have Private constructor in a Class?
And sometimes the answer given by the candidate is, No we cannot have private constructors.
So I would like to say, Yes you can have private Constructors in a class.
It is no special thing, try to think it this way,
Private: anything private can be accessed from within the class only.
Constructor: a method which has same name as that of class and it is implicitly called when object of the class is created.
or you can say, to create an object you need to call its constructor, if constructor is not called then object cannot be instantiated.
It means, if we have a private constructor in a class then its objects can be instantiated within the class only. So in simpler words you can say, if the constructor is private then you will not be able to create its objects outside the class.
What's the benefit
This concept can be implemented to achieve singleton object (it means only one object of the class can be created).
See the following code,
class MyClass{
private static MyClass obj = new MyClass();
private MyClass(){
}
public static MyClass getObject(){
return obj;
}
}
class Main{
public static void main(String args[]){
MyClass o = MyClass.getObject();
//The above statement will return you the one and only object of MyClass
//MyClass o = new MyClass();
//Above statement (if compiled) will throw an error that you cannot access the constructor.
}
}
Now the tricky part, why you were wrong, as already explained in other answers, you can bypass the restriction using Reflection.
I like the answers above, but there are two more nifty ways of creating a new instance of a class which has private constructor. It all depends on what you want to achieve and under what circumstances.
1: Using Java instrumentation and ASM
Well in this case you have to start the JVM with a transformer. To do this you have to implement a new Java agent and then make this transformer change the constructor for you.
First create the class transformer. This class has a method called transform. Override this method and inside this method you can use the ASM class reader and other classes to manipulate the visibility of your constructor. After the transformer is done, your client code will have access to the constructor.
You can read more about this here: Changing a private Java constructor with ASM
2: Rewrite the constructor code
Well, this is not really accessing the constructor, but still you can create an instance. Let's assume that you use a third-party library (let's say Guava) and you have access to the code but you don't want to change that code in the jar which is loaded by the JVM for some reason (I know, this is not very lifelike but let's suppose the code is in a shared container like Jetty and you can't change the shared code, but you have separate class loading context) then you can make a copy of the 3rd party code with the private constructor, change the private constructor to protected or public in your code and then put your class at the beginning of the classpath. From that point your client can use the modified constructor and create instances.
This latter change is called a link seam, which is a kind of seam where the enabling point is the classpath.
Using java Reflection as follows :
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
class Test
{
private Test() //private constructor
{
}
}
public class Sample{
public static void main(String args[]) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException
{
Class c=Class.forName("Test"); //specify class name in quotes
//----Accessing private constructor
Constructor con=c.getDeclaredConstructor();
con.setAccessible(true);
Object obj=con.newInstance();
}
}
Yes you could, as mentioned by #Jon Steet.
Another way of accessing a private constructor is by creating a public static method within this class and have its return type as its object.
public class ClassToAccess
{
public static void main(String[] args)
{
{
ClassWithPrivateConstructor obj = ClassWithPrivateConstructor.getObj();
obj.printsomething();
}
}
}
class ClassWithPrivateConstructor
{
private ClassWithPrivateConstructor()
{
}
public void printsomething()
{
System.out.println("HelloWorld");
}
public static ClassWithPrivateConstructor getObj()
{
return new ClassWithPrivateConstructor();
}
}
You can of course access the private constructor from other methods or constructors in the same class and its inner classes. Using reflection, you can also use the private constructor elsewhere, provided that the SecurityManager is not preventing you from doing so.
Yes, we can access the private constructor or instantiate a class with private constructor. The java reflection API and the singleton design pattern has heavily utilized concept to access to private constructor.
Also, spring framework containers can access the private constructor of beans and this framework has used java reflection API.
The following code demonstrate the way of accessing the private constructor.
class Demo{
private Demo(){
System.out.println("private constructor invocation");
}
}
class Main{
public static void main(String[] args){
try{
Class class = Class.forName("Demo");
Constructor<?> con = string.getDeclaredConstructor();
con.setAccessible(true);
con.newInstance(null);
}catch(Exception e){}
}
}
output:
private constructor invocation
I hope you got it.
I hope This Example may help you :
package MyPackage;
import java.lang.reflect.Constructor;
/**
* #author Niravdas
*/
class ClassWithPrivateConstructor {
private ClassWithPrivateConstructor() {
System.out.println("private Constructor Called");
}
}
public class InvokePrivateConstructor
{
public static void main(String[] args) {
try
{
Class ref = Class.forName("MyPackage.ClassWithPrivateConstructor");
Constructor<?> con = ref.getDeclaredConstructor();
con.setAccessible(true);
ClassWithPrivateConstructor obj = (ClassWithPrivateConstructor) con.newInstance(null);
}catch(Exception e){
e.printStackTrace();
}
}
}
Output:
private Constructor Called
Reflection is an API in java which we can use to invoke methods at runtime irrespective of access specifier used with them.
To access a private constructor of a class:
My utility class
public final class Example{
private Example(){
throw new UnsupportedOperationException("It is a utility call");
}
public static int twice(int i)
{
int val = i*2;
return val;
}
}
My Test class which creates an object of the Utility class(Example)
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
class Test{
public static void main(String[] args) throws Exception {
int i =2;
final Constructor<?>[] constructors = Example.class.getDeclaredConstructors();
constructors[0].setAccessible(true);
constructors[0].newInstance();
}
}
When calling the constructor it will give the error
java.lang.UnsupportedOperationException: It is a utility call
But remember using reflection api cause overhead issues
Look at Singleton pattern. It uses private constructor.
Yes you can instantiate an instance with a private constructor using Reflection, see the example I pasted below taken from java2s to understand how:
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
class Deny {
private Deny() {
System.out.format("Deny constructor%n");
}
}
public class ConstructorTroubleAccess {
public static void main(String... args) {
try {
Constructor c = Deny.class.getDeclaredConstructor();
// c.setAccessible(true); // solution
c.newInstance();
// production code should handle these exceptions more gracefully
} catch (InvocationTargetException x) {
x.printStackTrace();
} catch (NoSuchMethodException x) {
x.printStackTrace();
} catch (InstantiationException x) {
x.printStackTrace();
} catch (IllegalAccessException x) {
x.printStackTrace();
}
}
}
The basic premise for having a private constructor is that having a private constructor restricts the access of code other than own class' code from making objects of that class.
Yes we can have private constructors in a class and yes they can be made accessible by making some static methods which in turn create the new object for the class.
Class A{
private A(){
}
private static createObj(){
return new A();
}
Class B{
public static void main(String[]args){
A a=A.createObj();
}}
So to make an object of this class, the other class has to use the static methods.
What is the point of having a static method when we are making the constructor private?
Static methods are there so that in case there is a need to make the instance of that class then there can be some predefined checks that can be applied in the static methods before creation of the instance. For example in a Singleton class, the static method checks if the instance has already been created or not. If the instance is already created then it just simply returns that instance rather than creating a new one.
public static MySingleTon getInstance(){
if(myObj == null){
myObj = new MySingleTon();
}
return myObj;
}
We can not access private constructor outside the class but using Java Reflection API we can access private constructor. Please find below code:
public class Test{
private Test()
System.out.println("Private Constructor called");
}
}
public class PrivateConsTest{
public void accessPrivateCons(Test test){
Field[] fields = test.getClass().getDeclaredFields();
for (Field field : fields) {
if (Modifier.isPrivate(field.getModifiers())) {
field.setAccessible(true);
System.out.println(field.getName()+" : "+field.get(test));
}
}
}
}
If you are using Spring IoC, Spring container also creates and injects object of the class having private constructor.
I tried like this it is working. Give me some suggestion if i am wrong.
import java.lang.reflect.Constructor;
class TestCon {
private TestCon() {
System.out.println("default constructor....");
}
public void testMethod() {
System.out.println("method executed.");
}
}
class TestPrivateConstructor {
public static void main(String[] args) {
try {
Class testConClass = TestCon.class;
System.out.println(testConClass.getSimpleName());
Constructor[] constructors = testConClass.getDeclaredConstructors();
constructors[0].setAccessible(true);
TestCon testObj = (TestCon) constructors[0].newInstance();
//we can call method also..
testObj.testMethod();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Simple answer is yes we can have private constructors in Java.
There are various scenarios where we can use private constructors. The major ones are
Internal Constructor chaining
Singleton class design pattern
Also have another option create the getInstance() where we can create instance of private constructor inside same class and return that object.
class SampleClass1{
private SampleClass1() {
System.out.println("sample class constructor");
}
public static SampleClass1 getInstance() {
SampleClass1 sc1 = new SampleClass1();
return sc1;
}
}
public class SingletonDemo {
public static void main(String[] args) {
SampleClass1 obj1 = SampleClass1.getInstance();
}
}
We can create instance of private class by creating createInstance() in the same class and simply call the same method by using class name in main():
class SampleClass1{
private SampleClass1() {
System.out.println("sampleclass cons");
}
public static void createInstance() {
SampleClass1 sc = new SampleClass1();
}
}
public class SingletonDemo {
public static void main(String[] args) {
//SampleClass1 sc1 = new SampleClass1();
SampleClass1.createInstance();
}
}
Well, you can also if there are any other public constructors. Just because the parameterless constructor is private doesn't mean you just can't instantiate the class.
you can access it outside of the class its very easy to access
just take an example of singaltan class we all does the same thing make the private constructor and access the instance by static method here is the code associated to your query
ClassWithPrivateConstructor.getObj().printsomething();
it will definately work because i have already tested

How to invoke a method in java using reflection

How can I invoke a method with parameters using reflection ?
I want to specify the values of those parameters.
Here's a simple example of invoking a method using reflection involving primitives.
import java.lang.reflect.*;
public class ReflectionExample {
public int test(int i) {
return i + 1;
}
public static void main(String args[]) throws Exception {
Method testMethod = ReflectionExample.class.getMethod("test", int.class);
int result = (Integer) testMethod.invoke(new ReflectionExample(), 100);
System.out.println(result); // 101
}
}
To be robust, you should catch and handle all checked reflection-related exceptions NoSuchMethodException, IllegalAccessException, InvocationTargetException.
To call a class method using reflection is very simple.
You need to create a class and generate method in it. like as follows.
package reflectionpackage;
public class My {
public My() {
}
public void myReflectionMethod() {
System.out.println("My Reflection Method called");
}
}
and call this method in another class using reflection.
package reflectionpackage;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectionClass {
public static void main(String[] args)
throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Class c=Class.forName("reflectionpackage.My");
Method m=c.getDeclaredMethod("myReflectionMethod");
Object t = c.newInstance();
Object o= m.invoke(t);
}
}
Find more details here.
You can use getClass in any Object to discover its class. Then you can use getMethods to discover all the available methods. Once you have the correct method you can call invoke with any number of parameters
this is the easiest way I know of, it needs to be surrounded with try & catch:
Method m = .class.getDeclaredMethod("", arg_1.class, arg_2.class, ... arg_n.class);
result = () m.invoke(null,(Object) arg_1, (Object) arg_2 ... (Object) arg_n);
this is for invoking a static method, if you want to invoke a non static method, you need to replace the first argument of m.invoke() from null to the object the underlying method is invoked from.
don't forget to add an import to java.lang.reflect.*;

Categories