This question already has an answer here:
How to dynamically create new class implementing some interface and instantiate it?
(1 answer)
Closed 2 years ago.
Is it possible to instantiate an interface just using java reflections?
I would like to have a factory method - producing interfaces, just by knowing its class.
public interface IReflection {
public default String say(){
return "test default";
}
}
public <T> T factoryProduce(Class<T> type){
// how to instantiate on factoryProduce(IReflection.class)
}
I am trying to simulate the following using reflections.
Because for the following I can not dynamically get the interface class
return new IReflection(){}
Using newInstance() failed, cause there is no constructor in the interface.
Constructor<?>[] con = IReflection.class.getDeclaredConstructors(); // empty
i = IReflection.class.newInstance(); // no constructor
i = IReflection.class.getDeclaredConstructor().newInstance(); // no constructor
Interfaces don't have constructors. They don't take part in the chain of constructors, implicitly or explicitly, calling super from the most derived class to java.lang.Object.
I suggest avoiding reflection, but if you absolutely have to for some reason, there is java.lang.reflect.Proxy. Unfortunately it does proxy default methods. There is this answer as a dirty hack around, or write a class loader to load a simple subtype.
An interface cannot be instantiated, not even with reflection (and not even when all its methods have a default implementation). You can only instantiate a class that implements the interface.
If you have a small set of interfaces that you need factoryProduce to support, you can simply create an implementing class for each of them, and create a map from interface type to implementing class. factoryProduce can then get the implementing class from this map, and instantiate it with reflection.
If you really need a completely dynamic solution, look at dynamic proxies, which are capable of creating a class at runtime that implements a given set of interfaces.
You cannot - of course - instantiate the interface, but you can instantiate the Class object defining the interface.
It is possible to compile the interface "on the fly" from a String containing the definition using javax.tools.JavaCompiler obtained from ToolProvider.getSystemJavaCompiler() and then use the java.lang.ClassLoader.defineClass() to define the class on the fly.
PS: I am using this technique in Obba, an Object Handler for Spreadsheets (there is an example that creates a class from a String containing the code during runtime).
Related
I am creating an interface with many implementing classes and there is an attribute they must all have;
I guess it's better to put that attribute in their interface than writing many constructor lines, but attributes can only be static final and require to be immediately initialized.
public interface Interface{
static final AttrType attribute = new AttrType( *something* );
I have 2 problems: this attribute is a class and its constructor needs some other type parameters not just ints, and also it shouldn't be initialized here, I need all implementing classes of the interface to work on the same instance of AttrType which as i said I won't instantiate in the interface.
So, as I am not expert enough, is there a way to do this in the interface or I should just write a line in every subclass' constructor to put in the one AttrType instance they need?
Java interfaces describe what a class can do, rather than what a class is. Therefore, an interface only describes methods.
You could handle this in a few ways:
Using an interface, you could have a getter for the variable, which would force the implementing classes to have the variable. Something like "public AttrType getAttribute();"
Or you could create a class, probably abstract, which implements the interface and has the variable, and its getter and setter. The subclasses all would inherit this variable and behavior.
Would it be possible to add also a common base class to go with your common interface which all the classes could inherit? Then the common base class constructor could contain the attribute instance. Also you could consider using an abstract class instead of interface.
I'm dealing with a contractor's code. For whatever reason he has made a series of "constants" files that are all interfaces. They look like this:
interface SomeTypeConsts {
public static class SomeSubTypeA {
public static final String CONSTANT_A = "foo";
public static final String CONSTANT_B = "bar";
}
public static class SomeSubTypeB {
public static final String CONSTANT_A = "baz";
}
}
and so forth. There are no unimplemented/abstract methods, the files just contain nested classes some arbitrary level deep, and static final Strings for the constants. I cannot modify the contractor's code at this time.
I'm writing a test framework and I need an instance of one of these constants interfaces. All of them follow the above pattern, but my method needs to support all of them and not just one in specific.
I tried instantiating the interface using Reflection like this:
clazz.newInstance() // where clazz is Class<SomeTypeConsts>
But it threw a java.lang.InstantiationException.
All of the questions here on SO say that you need to implement the interface first, then use that instance. And if I knew ahead of time which const interface it was, I could easily do SomeTypeConsts consts = new SomeTypeConsts(){};. But I haven't been able to figure out how to do this with reflection, when all I have to work with is the Class<SomeTypeConst>.
Given an interface Class reference, with no abstract methods to be overwritten/implemented, how can I instantiate an instance of it using reflection?
You could do this using a JDK proxy for the interface, but it would be entirely pointless: If all you're doing is accessing static members, all of that is resolved without reference to any actual instance of the type in question, either at compile-time (far preferable) or at runtime with some approach like enumerating the fields and filtering on the static ones.
From the language spec (emphasis mine):
This type has no instance variables, and typically declares one or more abstract methods; otherwise unrelated classes can implement the interface by providing implementations for its abstract methods. Interfaces may not be directly instantiated.
And, from the Javadoc of Class.newInstance():
[throws] InstantiationException - if this Class represents an abstract class, an interface, an array class, a primitive type, or void; or if the class has no nullary constructor; or if the instantiation fails for some other reason.
You can't instantiate an interface. You can only instantiate (non-abstract) classes which implement it.
No. You cannot do that. Interfaces by definition are not instantiable.
What you need is a mock object. Not reflection
I have a small question on java interfaces
Is there any way to add a new method to java interface without modifying the classes that are implementing it.
condition is that I should not introduce new interface
Is there any way to add a new method to java interface without modifying the classes that are implementing it.
No.
condition is that I should not introduce new interface
If the condition also includes not modifying the many classes that directly implement the interface, you have been given an impossible task.
This is the reason why interfaces are often accompanied by abstract Adapter classes, that implement all the methods in a do-nothing way. Implementation classes then extend the adapter rather than implementing the interface, so that if you need to add an interface you only need to modify the interface and the adapter.
What you are trying to do is fundamentally impossible. Unless (as was just pointed out in the comments) you use Java 8.
Java 8 has introduced a concept of default or defender methods that allow you to add a method to an interface and provide a default implementation of that method within the interface.
http://zeroturnaround.com/rebellabs/java-8-explained-default-methods/
The rest of the answer applies to any version of Java before 8:
An interface describes the methods in a class. If you add a new method to an interface then all classes that implement the interface must implement the method. Unless by some stroke of luck the method you are adding already exists in every single implementing class this is just impossible without either adding a new interface or changing the classes.
If your interface were an Abstract Class then you could add a stub method that does nothing and allow that to be overridden but interfaces have no concept of optional methods.
By using abstract class we can solve this problem.
interface A{
void a();
void b();
}
Class a implement A
Class b implement A ...
if any new method arrive to create an abstract class and add that method into it
abstract class adapter {
abstract void c();
}
now extend this adapter class for necessary classes..
This hasn't been covered in my course and I am having trouble thinking up a reason why would I want this. I've come across the code below:
OpenNetworking proxy = service.getPort(OpenNetworking.class);
In the above line I can see that it is returning the port and it is passing the class to the method but I read this as the OpenNetworking.class isn't instantiated yet. I'm obviously missing something.
This is an example of a Factory method pattern.
The class type is provided to the service to give a Port on the specified type OpenNetworking.
A class type, in this case, is handy as it is a simplest way to provide a unique identifier to an object when doing object creation. It doesn't need to be maintained, should the state of the object changes as the class contains the type of the object.
There can be many reasons to do that:
Controlling number of instances of a class: Say you want to control how many instances you want for a class, you can make constructor
private or package level and return same instance when somebody calls
your method
Security: You might want your class to be secure and generally don't want to allow anybody to instantiate your class.
Dependency: Your class might have dependency which can be figured out only at runtime and then service class use reflection to
instantiate class appropriately.
Here we are passing the class type (Class in Java). So the treatment in the method getPort is done based on the Type of Class, we don't need an Object instance to handle it.
It is different, of course, than this code (whic doesn't compile):
OpenNetworking proxy = service.getPort(new OpenNetworking());
Also because of limitations of generics, when you have a generic class/method and you need to create a new instance, you will need a class. For example:
class SomeClass<T> {
public static<T> T create() {
return new T(); // will not work
}
public static<T> T create(Class<T> clazz) {
return clazz.newInstance(); //will work
}
}
so you need class instance to create a new object of that type.
Apparently the method service.getPort(); behaves according to the type in the parameter, imagin that there is a port for openNetworking and another one for closeNetworking, so providing the class name as a parameter would be enough to get the needed port number, one can create an enumeration for that but then extending existing code would force you to extend your enumeration too for each type.
The used method has this definition:
public <T> T getPort(Class<T> serviceEndpointInterface)
So it returns an instance of an object which extends the class T (a proxy,synthetic class instance)
I have two classes A and B which both implment the interface Z. Now, class A should for some functions of Interface Z (Z.f1, Z.f2, Z.f3, ...) only work as dispatcher to an object of class B.
public class A implements Z{
private B b; //instantiated in constructor of A
#Override
public String f1(int p)
{
return b.f1(p);
}
...
Is there a generic way to do this in Java?
If you mean that method f1() is declared in interface Z the pattern you want to implement is called wrapper or decorator.
In java you can create generic implementation using dynamic proxy introduced to java 1.4.
I don't think so. But sometimes your IDE can assist in creating all the simple methods to delegate the calls. And sometimes you can find third part classes to do this. For example, Guava (http://code.google.com/p/guava-libraries/) has a ton of ForwardingXXX classes, which, by default, delegate everything to something else. For example, ForwardingMap delegates all calls to another Map. You need to override the methods that you do NOT want to delegate.