Cast a class that is dynamically obtained - java

I am trying to cast a class that I dynamically obtain that has implemented an interface. I have tried the following below but it doesn't seem to work. How I achieve this.
public InterfaceX test(){
InterfaceX x = null;
Class<?> classX = Class.forName("com.TestClassX");
x = (InterfaceX) classX;
return x;
}
EDIT:
I dont want to create an instance, since I am just looking to simply call a static method defined by the interface.

If x is a Class object, you cannot do x.staticMethod(). However, this is possible using reflection.
public interface Interface {
static void method() {
System.out.println("Hello, World!");
}
}
Then, in the main class you can do this.
import java.lang.reflect.*;
public class Main {
public static void invokeMethod(String className) {
try {
Class<?> clazz = Class.forName(className);
Method method = clazz.getDeclaredMethod("method");
method.invoke(null); // null is used for static methods. For instance methods, pass the instance.
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
invokeMethod("Interface");
}
}
This works, but you should generally try to avoid using reflection (anything in java.lang.reflect). Most of the time there is a better solution to the problem you are trying to solve.

Related

Inline Java method defined for a class is not available when calling the object [duplicate]

Is there any Java syntax to access new methods defined within anonymous inner classes from outer class? I know there can be various workarounds, but I wonder if a special syntax exist?
For example
class Outer {
ActionListener listener = new ActionListener() {
#Override
void actionPerformed(ActionEvent e) {
// do something
}
// method is public so can be accessible
public void MyGloriousMethod() {
// viva!
}
};
public void Caller() {
listener.MyGloriousMethod(); // does not work!
}
}
MY OWN SOLUTION
I just moved all methods and members up to outer class.
Once the anonymous class instance has been implicitly cast into the named type it can't be cast back because there is no name for the anonymous type. You can access the additional members of the anonymous inner class through this within the class, in the expression immediate after the expression and the type can be inferred and returned through a method call.
Object obj = new Object() {
void fn() {
System.err.println("fn");
}
#Override public String toString() {
fn();
return "";
}
};
obj.toString();
new Object() {
void fn() {
System.err.println("fn");
}
}.fn();
identity(new Object() {
void fn() {
System.err.println("fn");
}
}).fn();
...
private static <T> T identity(T value) {
return value;
}
A student in my class asked our professor if this could be done the other day. Here is what I wrote as a cool proof of concept that it CAN be done, although not worth it, it is actually possible and here is how:
public static void main(String[] args){
//anonymous inner class with method defined inside which
//does not override anything
Object o = new Object()
{
public int test = 5;
public void sayHello()
{
System.out.println("Hello World");
}
};
//o.sayHello();//Does not work
try
{
Method m = o.getClass().getMethod("sayHello");
Field f = o.getClass().getField("test");
System.out.println(f.getInt(o));
m.invoke(o);
} catch (Exception e)
{
e.printStackTrace();
}
}
By making use of Java's Method class we can invoke a method by passing in the string value and parameters of the method. Same thing can be done with fields.
Just thought it would be cool to share this!
Your caller knows listener as an ActionListener and therefore it doesn't know anything about that new method. I think the only way to do this (other than doing reflection gymnastics, which really would defeat the purpose of using an anonymous class, i.e. shortcut/simplicity) is to simply subclass ActionListener and not use an anonymous class.
Funny enough, this is now allowed with var construct (Java 10 or newer). Example:
var calculator = new Object() {
BigDecimal intermediateSum = BigDecimal.ZERO;
void calculate(Item item) {
intermediateSum = Numbers.add(intermediateSum, item.value);
item.sum= intermediateSum;
}
};
items.forEach(calculator::calculate);
Here with method reference, but works with dot method call as well, of course. It works with fields as well. Enjoy new Java. :-)
I found more tricks with var and anonymous classes here: https://blog.codefx.org/java/tricks-var-anonymous-classes/
No, it's imposible. You would need to cast the ActionListener to its real subclass name, but since it's anonymous, it doesn't have a name.
The right way to do it is using reflection:
import java.lang.reflect.InvocationTargetException;
public class MethodByReflectionTest {
public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
Object obj = new Object(){
public void print(){
System.out.println("Print executed.");
}
};
obj.getClass().getMethod("print", null).invoke(obj, null);
}
}
You can check here: How do I invoke a Java method when given the method name as a string?
Yes you can access the method see the example below if any doubt please comment
package com;
interface A
{
public void display();
}
public class Outer {
public static void main(String []args)
{
A a=new A() {
#Override
public void display() {
System.out.println("Hello");
}
};
a.display();
}
}

Adding a method to a class using anonymous class [duplicate]

Is there any Java syntax to access new methods defined within anonymous inner classes from outer class? I know there can be various workarounds, but I wonder if a special syntax exist?
For example
class Outer {
ActionListener listener = new ActionListener() {
#Override
void actionPerformed(ActionEvent e) {
// do something
}
// method is public so can be accessible
public void MyGloriousMethod() {
// viva!
}
};
public void Caller() {
listener.MyGloriousMethod(); // does not work!
}
}
MY OWN SOLUTION
I just moved all methods and members up to outer class.
Once the anonymous class instance has been implicitly cast into the named type it can't be cast back because there is no name for the anonymous type. You can access the additional members of the anonymous inner class through this within the class, in the expression immediate after the expression and the type can be inferred and returned through a method call.
Object obj = new Object() {
void fn() {
System.err.println("fn");
}
#Override public String toString() {
fn();
return "";
}
};
obj.toString();
new Object() {
void fn() {
System.err.println("fn");
}
}.fn();
identity(new Object() {
void fn() {
System.err.println("fn");
}
}).fn();
...
private static <T> T identity(T value) {
return value;
}
A student in my class asked our professor if this could be done the other day. Here is what I wrote as a cool proof of concept that it CAN be done, although not worth it, it is actually possible and here is how:
public static void main(String[] args){
//anonymous inner class with method defined inside which
//does not override anything
Object o = new Object()
{
public int test = 5;
public void sayHello()
{
System.out.println("Hello World");
}
};
//o.sayHello();//Does not work
try
{
Method m = o.getClass().getMethod("sayHello");
Field f = o.getClass().getField("test");
System.out.println(f.getInt(o));
m.invoke(o);
} catch (Exception e)
{
e.printStackTrace();
}
}
By making use of Java's Method class we can invoke a method by passing in the string value and parameters of the method. Same thing can be done with fields.
Just thought it would be cool to share this!
Your caller knows listener as an ActionListener and therefore it doesn't know anything about that new method. I think the only way to do this (other than doing reflection gymnastics, which really would defeat the purpose of using an anonymous class, i.e. shortcut/simplicity) is to simply subclass ActionListener and not use an anonymous class.
Funny enough, this is now allowed with var construct (Java 10 or newer). Example:
var calculator = new Object() {
BigDecimal intermediateSum = BigDecimal.ZERO;
void calculate(Item item) {
intermediateSum = Numbers.add(intermediateSum, item.value);
item.sum= intermediateSum;
}
};
items.forEach(calculator::calculate);
Here with method reference, but works with dot method call as well, of course. It works with fields as well. Enjoy new Java. :-)
I found more tricks with var and anonymous classes here: https://blog.codefx.org/java/tricks-var-anonymous-classes/
No, it's imposible. You would need to cast the ActionListener to its real subclass name, but since it's anonymous, it doesn't have a name.
The right way to do it is using reflection:
import java.lang.reflect.InvocationTargetException;
public class MethodByReflectionTest {
public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
Object obj = new Object(){
public void print(){
System.out.println("Print executed.");
}
};
obj.getClass().getMethod("print", null).invoke(obj, null);
}
}
You can check here: How do I invoke a Java method when given the method name as a string?
Yes you can access the method see the example below if any doubt please comment
package com;
interface A
{
public void display();
}
public class Outer {
public static void main(String []args)
{
A a=new A() {
#Override
public void display() {
System.out.println("Hello");
}
};
a.display();
}
}

How to get class from field?

I am trying to receive class field value via reflection. But when I call my code I receive exception: IllegalArgumentException: Can not set class field field to java.lang.Class. (I am calling from javaagent)
My code:
private static Class<?> GetInstance(Class<?> clz) throws NoSuchFieldException, IllegalAccessException {
Class<?> clazz1 = null;
Field f = clz.getDeclaredField("INSTANCE");
f.setAccessible(true);
clazz1 = f.get(clz).getClass();
return clazz1;
}
private static Class GetClassLoader(Class<?> clz) throws NoSuchFieldException, IllegalAccessException, InstantiationException {
Field f = clz.getDeclaredField("classLoader");
f.setAccessible(true);
Class cls = f.get(clz).getClass();
return cls;
}
public static void agentmain(String agentArgs, Instrumentation inst){
try{
inst.addTransformer(new ClientTransfomer());
Class<?> FMLDeobfuscatingRemapper = null;
Class<?> InstanceClass;
Class<?>[] classes = inst.getAllLoadedClasses();
for(int i = 0;i < classes.length;i++){
if(classes[i].getName().contains("cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper")){
FMLDeobfuscatingRemapper = classes[i];
}
}
Class<?> instance = GetInstance(FMLDeobfuscatingRemapper);
Class cloader = GetClassLoader(instance);
Method m = cloader.getDeclaredMethod("findClass");
m.setAccessible(true);
m.invoke(null, "net.minecraft.client.entity.EntityClientPlayerMP");
}catch (Exception e){
}
How to get class from field?
With fieldValue.getClass(). Reflection not required.
Your code makes no sense.
You have a method called GetInstance() which returns a Class, not an instance. You need to change the return value of this method to Object and remove the getClass() call inside it.
You have a method called GetClassLoader() which returns a Class, not a ClassLoader. You need to change the return type of this method to ClassLoader, and remove the getClass() call inside it.
You are then reflectively treating this object as though it was a ClassLoader, which it isn't, and trying to call findClass() on it.
But I can see no necessity for using a reflection at all here once you have the instance: you can just call getClass().getClassLoader().findClass() directly.
You mean something like that?
public class One {
public Two two = new Two();
}
public class Two {
public void hello(){
System.out.println("hello");
}
}
public static void main(String[] args) {
public static void main(String[] args) {
One one = new One();
Class<?> clazz = one.getClass();
try {
Field twoField = clazz.getField("two");
twoField.setAccessible(true);
Class<?> twoClazz =Class.forName(twoField.getType().getName());
Method method = twoClazz.getMethod("hello", null);
method.invoke(twoClazz.newInstance(), null);
} catch (NoSuchFieldException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | ClassNotFoundException | InstantiationException e) {
e.printStackTrace();
}
}
}
Use getType() like below:
clz.getDeclaredField("fieldName").getType()

Creating new instance of generic Type in java [duplicate]

This question already has answers here:
Instantiating generics type in java
(12 answers)
Closed 2 years ago.
I know Java's generics are somewhat inferior to .Net's.
I have a generic class Foo<T>, and I really need to instantiate a T in Foo using a parameter-less constructor. How can one work around Java's limitation?
One option is to pass in Bar.class (or whatever type you're interested in - any way of specifying the appropriate Class<T> reference) and keep that value as a field:
public class Test {
public static void main(String[] args) throws IllegalAccessException,
InstantiationException {
Generic<Bar> x = new Generic<>(Bar.class);
Bar y = x.buildOne();
}
}
public class Generic<T> {
private Class<T> clazz;
public Generic(Class<T> clazz) {
this.clazz = clazz;
}
public T buildOne() throws InstantiationException, IllegalAccessException {
return clazz.newInstance();
}
}
public class Bar {
public Bar() {
System.out.println("Constructing");
}
}
Another option is to have a "factory" interface, and you pass a factory to the constructor of the generic class. That's more flexible, and you don't need to worry about the reflection exceptions.
And this is the Factory implementation, as Jon Skeet suggested:
interface Factory<T> {
T factory();
}
class Araba {
//static inner class for Factory<T> implementation
public static class ArabaFactory implements Factory<Araba> {
public Araba factory() {
return new Araba();
}
}
public String toString() { return "Abubeee"; }
}
class Generic<T> {
private T var;
Generic(Factory<T> fact) {
System.out.println("Constructor with Factory<T> parameter");
var = fact.factory();
}
Generic(T var) {
System.out.println("Constructor with T parameter");
this.var = var;
}
T get() { return var; }
}
public class Main {
public static void main(String[] string) {
Generic<Araba> gen = new Generic<Araba>(new Araba.ArabaFactory());
System.out.print(gen.get());
}
}
Output:
Constructor with Factory<T> parameter
Abubeee
Here's a rather contrived way to do it without explicitly using an constructor argument. You need to extend a parameterized abstract class.
public class Test {
public static void main(String [] args) throws Exception {
Generic g = new Generic();
g.initParameter();
}
}
import java.lang.reflect.ParameterizedType;
public abstract class GenericAbstract<T extends Foo> {
protected T parameter;
#SuppressWarnings("unchecked")
void initParameter() throws Exception, ClassNotFoundException,
InstantiationException {
// Get the class name of this instance's type.
ParameterizedType pt
= (ParameterizedType) getClass().getGenericSuperclass();
// You may need this split or not, use logging to check
String parameterClassName
= pt.getActualTypeArguments()[0].toString().split("\\s")[1];
// Instantiate the Parameter and initialize it.
parameter = (T) Class.forName(parameterClassName).newInstance();
}
}
public class Generic extends GenericAbstract<Foo> {
}
public class Foo {
public Foo() {
System.out.println("Foo constructor...");
}
}
I really need to instantiate a T in Foo using a parameter-less
constructor
Simple answer is "you cant do that" java uses type erasure to implment generics which would prevent you from doing this.
How can one work around Java's limitation?
One way (there could be others) is to pass the object that you would pass the instance of T to the constructor of Foo<T>. Or you could have a method setBar(T theInstanceofT); to get your T instead of instantiating in the class it self.
For Java 8 ....
There is a good solution at https://stackoverflow.com/a/36315051/2648077 post.
This uses Java 8 Supplier functional interface
Use The Constructor.newInstance method. The Class.newInstance method has been deprecated since Java 9 to enhance compiler recognition of instantiation exceptions.
public class Foo<T> {
public Foo()
{
Class<T> newT = null;
instantiateNew(newT);
}
T instantiateNew(Class<?> clsT)
{
T newT;
try {
newT = (T) clsT.getDeclaredConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
return newT;
}
}
From https://stackoverflow.com/a/2434094/848072. You need a default constructor for T class.
import java.lang.reflect.ParameterizedType;
class Foo<T> {
public bar() {
ParameterizedType superClass = (ParameterizedType) getClass().getGenericSuperclass();
Class<T> type = (Class<T>) superClass.getActualTypeArguments()[0];
try {
T t = (T) type.getDeclaredConstructor().newInstance();
//Do whatever with t
} catch (Exception e) {
// Oops, no default constructor
throw new RuntimeException(e);
}
}
}
Generics in Java are generally more powerful than in C#.
If you want to construct an object but without hardwiring a constructor/static method, use an abstract factory. You should be able to find detailed information and tutorials on the Abstract Factory Pattern in any basic design patterns book, introduction to OOP or all over the interwebs. It's not worth duplicating code here, other than to mention that Java's closure syntax sucks.
IIRC, C# has a special case for specifying a generic type has a no-args constructor. This irregularity, by definition, presupposes that client code wants to use this particular form of construction and encourages mutability.
Using reflection for this is just wrongheaded. Generics in Java are a compile-time, static-typing feature. Attempts to use them at runtime are a clear indication of something going wrong. Reflection causes verbose code, runtime failures, unchecked dependencies and security vulnerabilities. (Class.forName is particularly evil.)
I could do this in a JUnit Test Setup.
I wanted to test a Hibernate facade so I was looking for a generic way to do it. Note that the facade also implements a generic interface. Here T is the database class and U the primary key.
Ifacade<T,U> is a facade to access the database object T with the primary key U.
public abstract class GenericJPAController<T, U, C extends IFacade<T,U>>
{
protected static EntityManagerFactory emf;
/* The properties definition is straightforward*/
protected T testObject;
protected C facadeManager;
#BeforeClass
public static void setUpClass() {
try {
emf = Persistence.createEntityManagerFactory("my entity manager factory");
} catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError(ex);
}
}
#AfterClass
public static void tearDownClass() {
}
#Before
public void setUp() {
/* Get the class name*/
String className = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[2].getTypeName();
/* Create the instance */
try {
facadeManager = (C) Class.forName(className).newInstance();
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException ex) {
Logger.getLogger(GenericJPAController.class.getName()).log(Level.SEVERE, null, ex);
}
createTestObject();
}
#After
public void tearDown() {
}
/**
* Test of testFindTEntities_0args method, of class
* GenericJPAController<T, U, C extends IFacade<T,U>>.
* #throws java.lang.ClassNotFoundException
* #throws java.lang.NoSuchMethodException
* #throws java.lang.InstantiationException
* #throws java.lang.IllegalAccessException
*/
#Test
public void testFindTEntities_0args() throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException {
/* Example of instance usage. Even intellisense (NetBeans) works here!*/
try {
List<T> lista = (List<T>) facadeManager.findAllEntities();
lista.stream().forEach((ct) -> {
System.out.println("Find all: " + stringReport());
});
} catch (Throwable ex) {
System.err.println("Failed to access object." + ex);
throw new ExceptionInInitializerError(ex);
}
}
/**
*
* #return
*/
public abstract String stringReport();
protected abstract T createTestObject();
protected abstract T editTestObject();
protected abstract U getTextObjectIndex();
}
Quick solution that worked for me.
I see there is already an answer for this and this may not even be the best way to go about it. Also, for my solution you'll need Gson.
However, I ran into a situation where I needed to create an instance of a generic class of type java.lang.reflect.Type.
The following code will create an instance of the class you want with null instance variables.
T object = new Gson().fromJson("{}", myKnownType);
Where myKnownType is known before hand and obtained via TypeToken.getType().
You can now set appropriate properties on this object. Again, this may not be the best way to do this but it works as a quick solution if that's what you need.

Invoke Super class methods using Reflection

I have 2 classes, say A & B:
Class A extends B {
public void subClassMthd(){
System.out.println("Hello");
}
}
Class B {
public void printHelloWorld {
System.out.println("Hello");
}
}
Now, I am using reflection to invoke the methods on Class A. I would also like to invoke the printHelloWorld method present in Class B.
I tried using
Class clazz = Class.forName("com.test.ClassA");
Object classAInstance= clazz.newInstance();
Method superClassmthd = classAInstance.getClass()
.getSuperclass().getMethod("printHelloWorld", null);
superClassmthd.invoke(classAInstance);
Also tried as
Class clazz = Class.forName("com.test.ClassA");
Object classAInstance= clazz.newInstance();
Class superClazz = Class.forName(classAInstance.getClass().getSuperclass().getName());
Object superclassInstance = superClazz.newInstance();
Method superClassmthd = superclassInstance.getMethod("printHelloWorld", null);
superClassmthd.invoke(superclassInstance );
But none of them work; they throw an InstantiationException.
What am I doing wrong here?
Try this:
Method mthd = classAInstance.getClass().getSuperclass().getDeclaredMethod("XYZ");
mthd.invoke(classAInstance)
The difference is using getDeclaredMethod(), which gets methods of all visibilities (public, protected, package/default and private) instead of getMethod(), which only gets methods with public visibility.
What is the visibility of the methods you want to call (public, private etc).
If you want to see methods which you cannot call directly, you should use getDeclaredMethod().
Also, what the the constructors of your classes like? InstantiationException indicates that you are having trouble getting an instance of class A (or B).
I have the following code and it works:
A.java
import java.lang.reflect.Method;
public class A extends B {
public static void main(String[] args) throws Exception {
A classAInstance = new A();
Method mthd = classAInstance.getClass().getSuperclass().getMethod("XYZ", null);
mthd.invoke(classAInstance);
}
}
B.java
public class B {
public void XYZ() {
System.out.println("done");
}
}

Categories