correct way to instantiate bunch of classes at once - java

I have a class Main.java in which I need to instantiate a bunch of other classes say C1.java ... C50.java. I am not able to think of an elegant way to instantiate these 50 classes in Main class. If I simply put all instantiating code in one place it looks so crowded and ugly. Today I have 50 classes to instantiate, tomorrow this count can increase to 100, then this situation will get worse. Can you please suggest an elegant way of instantiating all these classes without making Main class crowded with instantiation code. I am not aware of any design pattern to do this.
I am thinking to create an array of classes that needs to be instantiated and use reflection to instantiate them.

The answer depends on what purpose the classes would serve. However, if you don't mind to end up with an unordered collection of instantiated classes, there is a way to go using Reflections library and I guess also a shorted one in the matter of lines of code:
// find out all the classes implementing MyInterface
Set<Class<? extends MyInterface>> subTypes = reflections.getSubTypesOf(MyInterface.class);
// iterate those classes and instntinate them
List<MyInterface> objects = new ArrayList<>();
for (Class<? extends MyInterface> clazz: subtypes) {
objects.add(clazz.newInstance());
}
In any case, the whole design should be rethough.

The recommended solution is to use the service loader architecture.
Instantiating all registered implementations of MyInterface can be done as simple as
for(MyInterface my: ServiceLoader.load(MyInterface.class)) {
/* do something with <my> */
}
To make this work, its not enough to just implement the interface, these implementations must be declared as service providers, either via an entry in META-INF/services/ of your jar file (as described in the linked class documentation) or via provides declaration within a Java module declaration when using Java 9 or newer.
The advantage of this is not only a higher performance, compared to searching the entire class path with a reflection library, it also ensures that the necessary access rights are established when using Java’s module system in the future.
See also Java 9’s version of the class documentation.

Related

Check if object is instanceof a protected class

Say I am using a Java library that has the following method
public static SomeInterface foo();
The interface SomeInterface has multiple implementations, some of which are protected within the library's package. One of these implementation is TheProtectedClass
What would be the best way to check if the object returned by foo() is an instance of TheProtectedClass?
My current plan is to create an Utils class that lives within my project but in the same package as the protected class. This Utils can refer to TheProtectedClass since it is in the same package and thus it can check if an object is instanceof TheProtectedClass.
Any other ideas?
EDIT: Some people are asking "why" so here is more context.
I am using jOOQ and in some part of my code, I want to know if the Field instance that I have is an instance of Lower.
Currently, I use field.getName().equals("lower") but this isn't as robust as I'd like it to be.
I realize that since Lower is a protected class, it isn't part of the API and that it can change but I am ok with that.
Class.forName("TheProtectedClass").isAssignableFrom(foo())
although it is a bad idea for many reasons. You're breaking the encapsulation and the abstraction here. If it's package-private, you shouldn't have to concern with it outside. If it's protected, you should explicitly inherit from it and use the API provided by class for this case.
The less obvious but more correct solution is to get an instance of TheProtectedClass, and compare it by
guaranteedTPCInstance.getClass().isAssignableFrom(foo())
, while still being kind of hacky, at least is more portable and OOPy IMO.
As to your idea of creating a class in the same package as TheProtectedClass to avoid being package-private - it's a viable solution, but a) it breaks the basic principle of encapsulation and the programming contract of the TPC class; packaging is done by library/class authors for a reason - to prevent irresponsible data access and using private API or undocumented proprietary methods, b) it's not always possible (and shouldn't be possible in case of properly designed library classes), since those classes can be not only package-private, but final or effectively final (anonymous inner classes etc) - for the reasons described by Bloch in EJ 2nd, "favor composition over inheritance" item, see also Good reasons to prohibit inheritance in Java? Use of final class in Java etc c) you can't do it with some Java library classes, as you can't define your class to be and use e.g. java.lang package. As such, the only "portable" solution is through reflection and through what I described.
tl;dr The fact you can piggyback another package by mimicking its package definition is an obvious C-style deficiency of Java's syntax (allowing programmer to do what he shouldn't be able to normally do; same goes with some specific reflection methods); hacks made this way are neither maintainable nor safe.
NOTE: If you you expect to do something in a internal implementation-dependent and, at the same time, portable and maintainable (e.g. impervious to implementation changes/class name changes etc) way, you're obviously expecting the impossible.
It appears that the best solution is to create a package in your project that has the same package as the package-private class and either expose TheProtectedClass.class as a Class<?> or simply add a simple method that checks if your Object is instanceof TheProtectedClass.
This does not require reflection, it is fast and relatively safe (compilation will break if the package-private class changes name).

Factory class that automatically loads subclasses of specific superclass in Java?

Before I describe my problem let my say that I suspect I might simply lack the correct terms to search for, and that's why my searches here on stackoverflor haven't been fruitful. So links to answers would also be very much appreciated.
Im trying to make a library that has a Factory, lets call it "MyFactory". MyFactory has a method that returns objects of the abstract class "MySuper", but also one that exposes the avilable subclasses to "MySuper". The library is intended to be expanded on a lot, so subclasses of "MySuper" will be added often, and then library will be recompiled, and dumped into a library folder of the application that uses it.
What I want is to be able to add a subclass of "MySuper" to the library, and have "MyFactory" become aware of it, preferebly without having to do anything else than create a new sublass of "MySuper"..
So far I use reflection to make "MyFactory" create new instances of a "MySuper" type, by giving the class name to a method, like this:
public MySuper getSuperObject(String name) {
return (MySuper) Class.forName("my.package." + name).newInstance(); }
But how can I get the factory to expose alle the "MySuper" classes as f.x. a List of String, so the applications that use the library know what they can call? Can I iterate the content of a package?
I'm open for solutions, the most important part is that in the future it should be very hassle free to add new "MySuper" sub-classes..
Thanks :-)
UPDATE:
I just want to note that I have found a nice Java library that handles reflection in an easy way, and lets you search for subtypes of a specific class. So my problem can be solved with that library (I have tested it). Here is a link: http://code.google.com/p/reflections/
You are looking for a Generic Factory Pattern. Something like..
public static <T extends MySuper> T createDocument(Class<T> subClazz) throws InstantiationException, IllegalAccessException {
return subClazz.newInstance();
};
You may google for Generic Factory Pattern and you will find lots of examples.
The default class loader knows nothing about a class until it searches for it. It then looks in several places depending on the class path. If you depend on the class loader you will not be able to get the class into the list until it has already been asked for by name.
The most automatic solution may be to designate a location, such as a directory, for new classes extending MySuper. To construct the list of classes, look in that directory for class files, and use your favorite bytecode library to check them for classes that extend MySuper.
Another option is to have a configuration file that lists the extending class names.
I suggest creating an enum that contains the possible subclasses to MySuper. whenever you add a subclass add an entry in the enum for the same and then you can give that as an input to the getMySuperObject() method.
do comment if u think i have left something in this solution

Querying classes with arbitrary properties in Java classpath using the Reflections library

I have used in the past the Reflections library to query classes in my classpath having a particular annotation, or inheriting from a particular class.
This is very easy to do with Reflections since the library already provide methods that answer such specific queries.
For example, the code below illustrates how to query classes inheriting from SomeType and classes annotated with SomeAnnotation, looking for classes located in the package my.package.prefix (example taken from the documentation of the Reflection.java class):
Reflections reflections = new Reflections("my.package.prefix");
Set<Class<? extends SomeType>> subTypes = reflections.getSubTypesOf(SomeType.class);
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(SomeAnnotation.class);
However, in my current problem what I need to do is querying for classes having an arbitrary set of properties (e.g., a combination of a particular class name + existing annotations + whatever ). I do not know these properties in advance since they should be defined by the programmer using the library I am developing.
I envision that part of the solution will be something like asking the programmer to define a Strategy class with a boolean method answering if the class should be in the answer set or not.
For example, the programmer should implement an interface similar to:
public interface MyStrategy {
public boolean match(Class clazz);
}
So my question is, once I have this strategy object, how I can instruct the Reflections library to filter classes keeping only those that match according to the strategy class defined by the programmer ?
UPDATE:
Apparently the filtering part is not the most difficult task (thanks for the answer #MvG) but actually gathering all the classes to be filtered (typically classes in a set of base packages defined by the programmer).
So the idea is querying all the classes and then filtering them with the method:
ReflectionUtils.getAll(allClasses, predicate).
Then, in order to obtain the initial set of classes to be filtered, I tried with querying all the subtypes of Object in a particular package chosen by the programmer.
Below the code I used for this:
ConfigurationBuilder config = new ConfigurationBuilder();
FilterBuilder fb = new FilterBuilder();
fb.include(FilterBuilder.prefix("my.package.prefix"));
config.filterInputsBy(fb);
config.setUrls(ClasspathHelper.forPackage("my.package.prefix"));
config.setScanners(new SubTypesScanner(false)); //the first argument at the constructor of SubTypesScanner indicates if the Object class should be ignored
Reflections reflections = new Reflections(config);
Set<Class<? extends Object>> unfilteredClasses = reflections.getSubTypesOf(Object.class);
Is this the best (more efficient) solution ?
Does someone have any alternative idea ?. Thanks in advance !
Use com.google.common.base.Predicate to express your strategies, or wrap your own strategy objects into such predicates. Then you can write
ReflectionUtils.getAll(allClasses, predicate);
It seems that actually computing this allClasses iterable is going to be the more demanding task. I see no simple API for that at first glance. You'll probably have to access the underlying store directly, and turn class names to Class objects yourself. That means loading all the classes, which might be quite time-consuming, and might even fail in certain scenarios.

Getting the names of all Java classes declared in a package

I'm writing a functionality where it would be helpful to get the classes inside a certain package of my program. Also, I only want the classes that subclass a certain class.
I need the classes in order to call static methods on them.
Is there an automatic way to do this? If so, is it slow?
In case I was not clear, what I want is something like this:
ArrayList<Class<? extends MySuperClass>> classes = ;
classes.add(MyClass.class);
classes.add(MyClass2.class);
Instead of having to call add for each class, I would like to automatically get that class list.
The number of classes is small, so I would not mind declaring them manually if the automatic trick would be slow - this app is for a mobile platform.
In either way, I would also like to know how to call the static method for each method in the ArrayList:
// error The method nameOfStaticMethod is undefined for the type Class<capture#2-of ? extends MySuperClass>
classes.get(0).nameOfStaticMethod ();
Thanks for your comments.
Java doesn't provide this ability. There is no introspection at the package level. The classes could be records in a database, or on the other side of a network connection. There's no requirement for them to be stored and organized so as to facilitate enumerating them by package.
You could make a custom class loader and API to provide a method of listing the class names.
I too would like to list all classes in a package but so far the methods of doing this is pretty bad:
Like JOTN suggested - needs file access - not if it is a jar
Listing a JAR entries - well, also needs the jar file
Quoting a older SO question:
It isn't possible to query a Package for it's Classes (or even its subpackages). http://forums.sun.com/thread.jspa?threadID=341935&start=0&tstart=0 contains a very good discussion about why this is problematic, as well as a handful of solutions to your problem.
Anyways, here is how you invoke static methods on the class:
Method m = Integer.class.getMethod("toString", Integer.TYPE);
System.out.println(m.invoke(null, 123));

How to create an interface at Runtime

Assuming I have a class like
public class FooImpl
{
public void bar(){};
}
Is there a way to create its interface at runtime?
e.g.
public interface Foo
{
public void bar();
}
I have been looking into Javasssist and the truth is it's reflection that I'm interested in using the interface for (as Esko Luontola and Yishai stated)
So I want an interface that specifies a subset of the original class' methods to make a proxy from.
I came to realize there are more things to be concerned about like
Should you reuse that interface or create a new one each time?
The proxy class is effectively a new instance of type java.lang.reflect.Proxy, which might cause implications depending on the use case.
The last point made me wonder on how some frameworks manage to handle this, do they deep copy the object? do they encapsulate the proxy inside the original instance?
So maybe it's just easier (though maybe not as elegant) to require for the client code to create the interface for the class.
You can do it with some bytecode manipulation/generation during class loading, for example using ASM, Javassist or similar, maybe also AspectJ.
The important question is, why would you need to do that? No normal code can use the class through its interface, because the interface does not exist at compile time. You would either need to generate the code that uses the interface or use reflection - but in that case you might as well use the original class. And for the interface to be useful, you should probably also modify the original class so that it implements the generated interface (this can be done with the libraries I mentioned).
You can look at something like Javassist to create the class. You would go over the class with Class.getMethods() and have to implement the bytecode at runtime for the interface, and then use the Proxy class to bridge the interface and implementation.

Categories

Resources