public class Test {
public static void main(String[] args) throws Exception {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int num = Integer.parseInt(br.readLine().trim());
Object o;
Method[] methods = Inner.class.getEnclosingClass().getMethods();
for(int i=0;i<methods.length;i++) {
System.out.println(methods[i].invoke(new Solution(),8));
}
// Call powerof2 method here
} catch (Exception e) {
e.printStackTrace();
}
}
static class Inner {
private class Private {
private String powerof2(int num) {
return ((num & num - 1) == 0) ? "power of 2" : "not a power of 2";
}
}
}
}
Is it possible to call powerof2() method ?
I am getting java.lang.IllegalArgumentException: argument type mismatch for invoke
Yes, things declared in the same top-level class can always access each other:
public class Test {
public static void main(String[] args) throws Exception {
Inner i = new Inner(); // Create an instance of Inner
Inner.Private p = i.new Private(); // Create an instance of Private through
// the instance of Inner, this is needed since
// Private is not a static class.
System.out.println(p.powerof2(2)); // Call the method
}
static class Inner {
private class Private {
private String powerof2(int num) {
return ((num & num - 1) == 0) ? "power of 2" : "not a power of 2";
}
}
}
}
See Ideone
Reflection version:
public class Test {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException, NoSuchMethodException {
Class<?> privateCls = Inner.class.getDeclaredClasses()[0];
Method powerMethod = privateCls.getDeclaredMethod("powerof2", int.class);
powerMethod.setAccessible(true);
Constructor<?> constructor = privateCls.getDeclaredConstructors()[0];
constructor.setAccessible(true);
Object instance = constructor.newInstance(new Inner());
System.out.println(powerMethod.invoke(instance, 2));
}
static class Inner {
private class Private {
private String powerof2(int num) {
return ((num & num - 1) == 0) ? "power of 2" : "not a power of 2";
}
}
}
}
Related
I have this chained method call
Integer.parseInt(A.get().getC().getD().toString());
I need to make this with reflection. I know that I can use Class.forName(String class) and then invoke methods, but how do I save method results so I can call that chain.
Classes:
public class A
{
public static B get() { return new B(); }
}
public class B
{
public C getC() { return new C();}
}
public class C
{
public C getD() { return new D();}
}
Suppose we have this classes:
public class A {
public B getB() { return new B(); }
public static B getBStatic() { return new B(); }
}
public class B { public C getC() { return new C();}}
public class C { public String getD() { return "done"}}
Example 1:
public static void main(String[] args) throws Exception {
Class<A> clazz = A.class;
Constructor<A> constructor = clazz.getConstructor();
A instance = constructor.newInstance();
Method getMethod = clazz.getDeclaredMethod("getB");
Object b = getMethod.invoke(instance);
Method getCMethod = b.getClass().getDeclaredMethod("getC");
Object c = getCMethod.invoke(b);
Method getDMethod = c.getClass().getDeclaredMethod("getD");
String d = (String) getDMethod.invoke(c);
System.out.println(d); // done
}
Example 2:
public static void main(String[] args) throws Exception {
reflection(new A(), "getB", "getC", "getD"); // invoke non static methods
reflection(new A(), "getBStatic", "getC", "getD"); // invoke static and nonstatic methods
reflection(A.getBStatic(), "getC", "getD"); // provide object from static method
reflection(invokeStaticMethod(A.class, "getBStatic"), "getC", "getD"); // invoke static method without instance
}
public static Object invokeStaticMethod(Class<?> clazz, String methodName) throws Exception {
return clazz.getMethod(methodName).invoke(clazz);
}
public static void reflection(Object instance, String... methods) throws Exception {
Object item = instance;
for (String methodName : methods) {
item = item.getClass().getDeclaredMethod(methodName).invoke(item);
}
System.out.println(item); // done
}
I am trying to invoke a method using reflection.
The method I am invoking is not static and in the same class I am invoking it from.
A simplified version of my code:
public class Test {
public static void main(String[] args) {
Test instance = new Test();
if (args.length > 0) {
instance.doWork(args[0]);
}
}
private void doWork(String methodName) {
Method method;
try {
method = this.getClass().getMethod(methodName);
method.invoke(this);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
[...]
}
}
private void MethodOne() { ... };
private void MethodTwo() { ... };
[...]
private void MethodTwenty() { ... };
}
What I am getting is a java.lang.NoSuchMethodException: correct.package.and.class.MethodTwo() despite the package / class / method existing.
Can someone tell me what I am doing wrong?
What I am getting is a java.lang.NoSuchMethodException:
correct.package.and.class.MethodTwo()...
you are calling the getMethod() which is not giving back the private method
Assuming that arg[0] has the right name of the method (if not you'll get a java.lang.NoSuchMethodException again), 2 thing must be done here:
you need to use getDeclaredMethod (because MethodOne is private declared)
your need to set the flag for access to it .setAccessible(true) (this will allow you to invoke a method that is declared private)
Example:
Method method;
try {
method = f.getClass().getDeclaredMethod("doThis");
method.setAccessible(true);
method.invoke(f);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException e) {
System.err.println("Opala, somethign went wrong here!");
}
The way you are accessing method is correct.
The method access specifier is private. Thus it is throwing error.
Please change the access specifier to public, it will work.
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) {
Test instance = new Test();
if (args.length > 0) {
instance.doWork(args[0]);
}
}
private void doWork(String methodName) {
Method method;
try {
method = this.getClass().getMethod(methodName);
method.invoke(this);
} catch (Exception e) {
}
}
public void MethodOne() { System.out.println("Method 1"); };
public void MethodTwo() { System.out.println("Method 2"); };
public void MethodTwenty() { System.out.println("Method 3"); };
}
If you are trying to access private methods or constructors, you need to change the code.
Thanks,
Thiruppathi S
CLASS TO INVOKE METHODS FROM
public class Computer {
private String brandName;
private int yearManufactured;
public String getBrandName() {
return brandName;
}
public void setBrandName(String brandName) {
this.brandName = brandName;
}
public int getYearManufactured() {
return yearManufactured;
}
public void setYearManufactured(int yearManufactured) {
this.yearManufactured = yearManufactured;
}
}
IMPLEMENTATION CLASS
public class Test {
public static void main(String[] args) throws NoSuchMethodException,
InvocationTargetException, IllegalAccessException{
Class curClass = Computer.class;
Method[] allMethods = curClass.getDeclaredMethods();
Computer myComputer = new Computer();
for(int c = 0; c < allMethods.length; c++){
Class[] parameterTypes = allMethods[c].getParameterTypes();
for(Class parameterType: parameterTypes){
System.out.println(parameterType.getName());
switch(parameterType.getName()){
case "java.lang.String":
allMethods[c].invoke(myComputer, "LENOVO");
break;
case "int":
allMethods[c].invoke(myComputer, 2021);
break;
}
}
}
System.out.println("BRAND NAME :"+myComputer.getBrandName());
System.out.println("YEAR MANUFACTURED: "+myComputer.getYearManufactured());
}
}
public class Outer {
public Inner inner = new Inner();
public void test() {
Field[] outerfields = this.getClass().getFields();
for(Field outerf : outerfields) {
Field[] innerFields = outerfields[i].getType().getFields();
for(Field innerf : innerFields) {
innerf.set(X, "TEST");
}
}
}
public class Inner {
String foo;
}
}
What should X be? How can I get the referrence of the innerf field (variable inner)?
How can I get the referrence of the innerf field (variable inner)?
You don't need it. You only need a reference to an object that contains it: in this case, outerfields[i].get(this). See the Javadoc.
OK, I started this before the other answer was accepted, but here's a complete example:
import java.lang.reflect.Field;
public class Outer
{
public static void main(String[] args) throws Exception
{
Outer outer = new Outer();
outer.test();
System.out.println("Result: "+outer.inner.foo);
}
public Inner inner = new Inner();
public void test() throws Exception
{
Field[] outerFields = this.getClass().getFields();
for (Field outerField : outerFields)
{
Class<?> outerFieldType = outerField.getType();
if (!outerFieldType.equals(Inner.class))
{
// Don't know what to do here
continue;
}
Field[] innerFields = outerFieldType.getDeclaredFields();
for (Field innerField : innerFields)
{
Class<?> innerFieldType = innerField.getType();
if (!innerFieldType.equals(String.class))
{
// Don't know what to do here
continue;
}
// This is the "public Inner inner = new Inner()"
// that we're looking for
Object outerFieldValue = outerField.get(this);
innerField.set(outerFieldValue, "TEST");
}
}
}
public class Inner
{
String foo;
}
}
I have a function which calls another function in a different class which throws an exception based on the paraameter provided. I want
public class A {
public int f(int p){
{
B obj = new B();
obj.g(p);
}
}
public class B {
public int g(int p)
{
// throws an exception for this value of p
}
}
Is it possible that I can catch the exception in class A itself and handle it ? I can't change the implementation of class B.
Yeah just use a try-catch statement.
public class A {
public int f(int p){
{
B obj = new B();
try {
obj.g(p);
} catch ( /* the exception */ ) {
// handle the exception
}
}
}
public class B {
public int g(int p)
{
// throws an exception for this value of p
}
}
How to retrieve a static variable using its name dynamically using Java reflection?
If I have class containing some variables:
public class myClass {
final public static string [][] cfg1= {{"01"},{"02"},{"81"},{"82"}};
final public static string [][]cfg2= {{"c01"},{"c02"},{"c81"},{"c82"}};
final public static string [][] cfg3= {{"d01"},{"d02"},{"d81"}{"d82"}};
final public static int cfg11 = 5;
final public static int cfg22 = 10;
final public static int cfg33 = 15;
}
And in another class I want variable name is input from user:
class test {
Scanner in = new Scanner(System.in);
String userInput = in.nextLine();
// get variable from class myClass that has the same name as userInput
System.out.println("variable name " + // correct variable from class)
}
Using reflection. Any help please?
You need to make use of java reflect. Here is a sample code. For example, I accessed 'cfg1' variable using java reflection, and then printed it into the console. Look into the main method carefully. I have handled no exceptions for simplification. The key line here is:
(String[][]) MyClass.class.getField("cfg1").get(MyClass.class);
__ ^typecast__ ^accessingFeild______________ ^accessFromClassDefinition
public class MyClass {
final public static String[][] cfg1 = { { "01" }, { "02" }, { "81" },
{ "82" } };
final public static String[][] cfg2 = { { "c01" }, { "c02" }, { "c81" },
{ "c82" } };
final public static String[][] cfg3 = { { "d01" }, { "d02" }, { "d81" },
{ "d82" } };
final public static int cfg11 = 5;
final public static int cfg22 = 10;
final public static int cfg33 = 15;
public static void main(String[] args) throws IllegalArgumentException,
IllegalAccessException, NoSuchFieldException, SecurityException {
String[][] str = (String[][]) MyClass.class.getField("cfg1").get(
MyClass.class);
for (String[] strings : str) {
for (String string : strings) {
System.out.println(string);
}
}
}
}
If I well understood your needs, this could suit them:
// user input, hardcoded for the example
String fieldName = "cfg22";
MyClass blank = new MyClass();
Object value = null;
try {
value = MyClass.class.getDeclaredField(fieldName).get(blank);
} catch (IllegalArgumentException e) {
// if the specified object is not an instance of the class or
// interface declaring the underlying field (or a subclass or
// implementor thereof)
e.printStackTrace();
} catch (SecurityException e) {
// if a security manager, s, is present [and restricts the access to
// the field]
e.printStackTrace();
} catch (IllegalAccessException e) {
// if the underlying field is inaccessible
e.printStackTrace();
} catch (NoSuchFieldException e) {
// if a field with the specified name is not found
e.printStackTrace();
}
System.out.println(value);
Prints 10.
I merge the two above solutions and get:
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;
public class MyClass
{
final public static String[][] cfg1 = {{"01"}, {"02"}, {"81"},
{"82"}};
final public static String[][] cfg2 = {{"c01"}, {"c02"}, {"c81"},
{"c82"}};
final public static String[][] cfg3 = {{"d01"}, {"d02"}, {"d81"},
{"d82"}};
final public static int cfg11 = 5;
final public static int cfg22 = 10;
final public static int cfg33 = 15;
public static void main(String[] args) throws IllegalArgumentException,
IllegalAccessException, NoSuchFieldException, SecurityException
{
for (Field field : MyClass.class.getDeclaredFields()) {
if (!Modifier.isStatic(field.getModifiers())) {
System.out.println("Non-static field: " + field.getName());
}
else {
System.out.println("Static field: " + field.getName());
Object obj = MyClass.class.getField(field.getName()).get(MyClass.class);
if (obj instanceof String[][]) {
String[][] cad = (String[][]) obj;
for (String[] strings : cad) {
System.out.println("Values:: " + Arrays.toString(strings));
}
}
else {
System.out.println(" " + obj.toString());
}
}
}
}
}
You can try something like this :
for (Field field : myClass.class.getDeclaredFields()) {
if (!Modifier.isStatic(field.getModifiers())) {
System.out.println("Non-static field: " + field.getName());
}
else {
System.out.println("Static field: " + field.getName());
}
}
Use Field#get(Object obj) to get the value .
Note: Please follow Java naming conventions.
Just call Class.getField() or Class.getDeclaredField(), then call Field.getValue() on the result, providing null (or the class itself) as the parameter in the case of a static variable, or an instance of the class in the case of an instance variable.