Java8+: Pass Anonymous Object to Method - java

How can I pass an anonymous Object to a method (in an other class) and read the data like in the non-working example below?
public static void caller() {
Object obj = new Object() { final String name = "Aloha from Hawaii"; };
consumer(obj);
}
public static void consumer(Object obj) {
System.out.println(obj.name);
}

Regarding to the link provided by jdabtieu:
public static void consumer(Object obj) {
try {
System.out.println(obj.getClass().getDeclaredField("name").get(obj));
} catch (NoSuchFieldException | IllegalAccessException ignored) {
}
}
Is it really that complicated?
However, it's working - and if there is no better solution I'll stay with it.
Many thanks

Related

Java invoke method using reflection

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());
}
}

Call a class from another class without having to change the class type (or the return) Java

I am trying to run a class from another class. But it asks me to change the type when I store the class name in an array. I want the user to enter a number which would be fed into the array and run the class at that array value.
Here is my code so far:
public class All_Challenges {
public static void main(String[] args) {
System.out.println("Which class do you want to run?: ");
System.out.println("1. The first class");
Class[] theFiles = new Class[31];
theFiles[1] = Challenge_1_Whats_Your_Name.main(args);
theFiles[1].main(args);
}
}
The last two lines are giving me an error because they are making me change the class type from The void to type class and then making add a return statement. I have around 30 of these so I would prefer not to have to change my main method in all my other classes. What stuff should I write so that I don't have to do this. I think it's something to do with what "type" my array is. Or maybe it's to do with the line main.(args);
Weird part is that it doesn't ask me to change the type when I don't call it from an array.
The problem is that you are trying to put a method to array of classes.
Class[] theFiles = new Class[31];
theFiles[1] = Challenge_1_Whats_Your_Name.class;
try {
theFiles[1].getMethod("main", String[].class).invoke(args);
} catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
e.printStackTrace();
}
That should work for you
You can do it using reflections:
public class TestMain {
private static final Class<?>[] classArray = {A.class, B.class};
public static void main(String[] args) {
for (Class<?> classExec : classArray) {
try {
//get main
Method method = classExec.getMethod("main", String[].class);
method.invoke(null, (Object) args);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
public static class A {
public static void main(String[] args) {
System.out.println("A");
}
}
public static class B {
public static void main(String[] args) {
System.out.println("B");
}
}
}
Reference: https://stackoverflow.com/a/4980149/1255493

Manipulate Java object reference using class constructor

This was an exam question which I couldn't complete.
How do you get the following java code to print false by only
editing code within the MyClass constructor?
public class MyClass{
public MyClass(){
}
public static void main(String[] args) {
MyClass m = new MyClass();
System.out.println(m.equals(m));
}
}
You are NOT allowed to override the equals method, or change any of
the code within the main method. The code must run without the program
crashing.
According to my research, you can't set a Java object reference to null when you instantiate a class. So I'm officially stumped.
That was tough!!
public MyClass() {
System.setOut(new PrintStream(new FilterOutputStream(System.out) {
#Override
public void write(byte[] b, int off, int len) throws IOException {
if(new String(b).contains("true")) {
byte[] text = "false".getBytes();
super.write(text, 0, text.length);
}
else {
super.write(b, off, len);
}
}
}, true));
}
Or Paul Boddington's simplified version:
PrintStream p = System.out;
System.setOut(new PrintStream(p) {
#Override
public void println(boolean b) {
p.println(false);
}
});
Or AJ Neufeld's even more simple suggestion:
System.setOut(new PrintStream(System.out) {
#Override
public void println(boolean b) {
super.println(false);
}
});
Something along these lines, I would guess:
public MyClass() {
System.out.println(false);
System.exit(0);
}
EDIT: I found a puzzle very similar to yours in Java Puzzlers, except in that question the only restriction was that you could not override equals, which basically makes the solution to overload it instead and simply return false. Incidentally, my solution above was also given as an alternative answer to that puzzle.
Another solution is
public MyClass() {
new PrintStream(new ByteArrayOutputStream()).println(true);
try {
Field f = String.class.getDeclaredField("value");
f.setAccessible(true);
f.set("true", f.get("false"));
} catch (Exception e) {
}
}
The first line is needed because it is necessary for the string literal "true" to be encountered in the PrintStream class before the backing array is modified. See this question.
This is my solution
public class MyClass {
public MyClass() {
System.out.println("false");
// New class
class NewPrintStream extends PrintStream {
public NewPrintStream(OutputStream out) {
super(out);
}
#Override
public void println(boolean b) {
// Do nothing
}
}
NewPrintStream nps = new NewPrintStream(System.out);
System.setOut(nps);
}
public static void main(String[] args) {
MyClass m = new MyClass();
System.out.println(m.equals(m));
}
}
Basically, this is the variation of #fikes solution.

Dynamically invoke a method from a varying class

I have a requirement where in i need to invoke method from class in a particular pattern which is obtained as input argument.
public RandomMethod(String ClassName){
//Eg For Class Name Abc , there is a method AbcProcessor which i need to invoke
ClassName.ClassNameProcessor
}
Since i am getting the argument as String , i am not able to figure out how to cast String into a form where i can call something like Abc.AbcProcessor()
I believe there is some way to do this using reflections. But i am not sure how to proceed.
By reflection you can do that, try following sample:
Class A:
public class A {
public void print(){
System.out.println("A");
}
}
Class B:
public class B {
public void print(){
System.out.println("B");
}
}
Invoking print() from A and B:
public class Test {
public static void callPrint(String className){
try {
Class clazz = Class.forName(className);
Object obj = clazz.newInstance();
clazz.getDeclaredMethod("print").invoke(obj);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) {
callPrint("test.A");
callPrint("test.B");
}
}
You need to use reflecton, indeed:
public void randomMethod(String fullyQualifiedClassName, String methodName) throws ReflectiveOperationException {
Class<?> clazz = Class.forName(fullyQualifiedClassName);
clazz.getMethod(methodName).invoke(null);
}
which would work assuming you are calling public static method with no arguments

How to use same object between diffrent methods

I am novice to Java coding.
I wanted to know how to pass the same object between different methods?
Ex:
Class A
{
//Declaring an object say
Object obj;
public void Method1()
{
//Here i want to use some method of obj
obj=new Object();
obj.Metod1();
}
public void Method2()
{
//Here i want to use another method of obj
obj.Metod2();
}
}
class B
{
A aObj=new A();
aObj.Method1();
aObj.Method2();
}
From the above code, how can i use the object created in Method1() can be used in Method2?
This is my actual code:
public class UtilityFunctions
{
File fileName;
public static FileWriter fwObj;
public static BufferedWriter bwObj;
Logger App_log;
UtilityFunctions()
{
fileName=new File(System.getProperty("user.dir")+"\\src\\TempFile.html");
Logger App_log=Logger.getLogger(UtilityFunctions.class);
try
{
if(!fileName.exists())
fileName.createNewFile();
this.fwObj=new FileWriter(fileName);
this.bwObj=new BufferedWriter(fwObj);
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void writeHeader()
{
try
{
this.bwObj.append("<html><body><table border='1' style='widht:300px'><tbody><tr><th>Date</th><th>Position</th><th>Site</th></tr>");
this.bwObj.flush();
// this.bwObj.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void writeFooter()
{
try
{
this.bwObj.append("</html></body></table></tbody>");
this.bwObj.flush();
bwObj.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void writeReport(String strstrPositionName)
{
DateFormat format=new SimpleDateFormat("MM/dd/yyyy");
Date date=new Date();
String strCurrentDate=format.format(date);
try
{
String strFormattedString="<tr><td>"+strCurrentDate+"</td><td>"+strstrPositionName+"</td><td>SomeSite</td></tr>";
App_log.info("Printing the Line as: "+strFormattedString);
this.bwObj.append(strFormattedString);
this.bwObj.flush();
// bwObj.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
I would like to call above methods like
Class TempClass
{
public static void main(String args[] args)
{
UtilityFunctions obj=new UtilityFunctions();
obj.writeHeader();
obj.writeReport("Message1");
obj.writeReport("Message2");
// I may add many write Report statements here.
obj.writeFooter();
}
}
The problem i see here, writeHeader is working fine, but at execution of writeReport I am getting NullPointer Exception. How to overcome this?
java.lang.NullPointerException
at UtilityFunctions.writeReport(UtilityFunctions.java:71)
at TempClass.writeDetailedReport etc.........
Here is how you can pass the object frome one method to another
public void method1()
{
Object objToBePassed=new Object();
method2(objToBePassed);
}
public void method2(Object passedObject)
{
// your logic
}
You should create your objects within constructor of the class, and then you can easly use this object. for example:
class YourClass {
private Object obj;
public YourClass() { //constructor
obj = new Object();
}
public void method() {
//your logic
}
To sum up, If you create fields of your class in constructor you don't worry about null pointers and all of class methods have access to those objects. If you want to use private field outside your class, for example in method from other class you should use getter method and pass object in argument:
public void otherMethod(Object obj)
First declare your object as a field for your class:
class MyClass
{
private Object obj;
//...Rest of class goes here
}
Initialize the object in your constructor so that it is not null when you want to access it.
public MyClass()
{
this.obj = new Object();
}
Now you can access it from your two methods as you wish.
public method1()
{
this.obj.doSomething();
}
public method2()
{
this.obj.doSomethingElse();
}
All in all, it can look something like this:
class MyClass
{
private Object obj;
public MyClass()
{
this.obj = new Object();
}
public method1()
{
this.obj.doSomething();
}
public method2()
{
this.obj.doSomethingElse();
}
}
Now if you want to actually pass an object from one method to another but don't want it to be accessible to any other methods, you can make it a parameter like this:
public method1(Object obj)
{
obj.doSomething()
}
And then you can call the method from somewhere else passing specific instances of the object type.
public method2()
{
Object obj1 = new Object();
Object obj2 = new Object();
this.method1(obj1); //All actions in method1 will be done to obj1
this.method1(obj2); //All actions in method1 will be done to obj2
}
Passing parameters is especially useful if you want to call a single method several times, but have it act on different inputs.

Categories

Resources