How to Get a List of All the Implementations of an Interface Programmatically in Java

Get a list of all the implementations of an Interface in Android

You can use BaseActivity As abstract and check the the internet as per the network changes.

  • Require permissions
<!--Manifest.xml-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  • NetworkChangeListener.java
/* Interface required to call in each activity with whom you extends BaseActivity.java */
public interface NetworkChangeListener {
void networkAvailable();

void networkUnavailable();
}
  • BaseActivity.java

@SuppressLint("Registered")
public abstract class BaseActivity extends AppCompatActivity implements NetworkChangeListener {

private BroadcastReceiver networkStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
/* previous way of doing it*/
NetworkInfo ni = null;
if (manager != null) {
ni = manager.getActiveNetworkInfo();
}
if (ni != null && ni.isConnected()) {
networkAvailable();
} else {
networkUnavailable();
}
}
};

/*
* If you like to check it manually you also cam use the bellow function for it
* */

public void checkInternet() {
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
/* previous way of doing it*/
NetworkInfo ni = null;
if (manager != null) {
ni = manager.getActiveNetworkInfo();
}
if (ni != null && ni.isConnected())
networkAvailable();
else
networkUnavailable();
}

@Override
protected void onResume() {
super.onResume();
Log.e("NETWORK_STATE", "networkStateReceiver registerReceiver");
registerReceiver(networkStateReceiver, new IntentFilter(android.net.ConnectivityManager.CONNECTIVITY_ACTION));
}

@Override
protected void onPause() {
super.onPause();
Log.e("NETWORK_STATE", "networkStateReceiver unregisterReceiver");
unregisterReceiver(networkStateReceiver);
}
}


if you like to check the Internet manually you can use


/*
* If you like to check it manually you also cam use the bellow function for it
* */
public void checkInternet() {
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
/* previous way of doing it*/
NetworkInfo ni = null;
if (manager != null) {
ni = manager.getActiveNetworkInfo();
}
if (ni != null && ni.isConnected())
networkAvailable();
else
networkUnavailable();
}
  • MainActivity.java

public class MainActivity extends BaseActivity {

/*
* Check the log for the proper results
* */
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

@Override
public void networkAvailable() {
Log.e("NETWORK_STATE", "Connected");
}

@Override
public void networkUnavailable() {
Log.e("NETWORK_STATE", "Not Connected");
}
}

Also if anything missed please refer Github repo

Finding all classes implementing a specific interface

I had a similar need where I wanted to make sure that any classes created that implemented a certain interface were always truly serializable. I created a JavaClassFinder which walks through all directories in the classpath, and finds all classes assignable to the interface I cared about. Here is a code snippet:

public <T> List<Class<? extends T>> findAllMatchingTypes(Class<T> toFind) {
foundClasses = new ArrayList<Class<?>>();
List<Class<? extends T>> returnedClasses = new ArrayList<Class<? extends T>>();
this.toFind = toFind;
walkClassPath();
for (Class<?> clazz : foundClasses) {
returnedClasses.add((Class<? extends T>) clazz);
}
return returnedClasses;
}

I'm happy to share the code with you if it helps. The only draw back is that this will only handle .class files -- I didn't add the feature to unzip .jars and read class files from there. (But it wouldn't be a huge project to add that.)

UPDATE: I checked my source code for the above, and found it depends on a lot of helper classes in our standard utility library. To make it easier, I zipped up all the code needed, which you can download from JavaClassFinder.zip. This will set up directly in Eclipse, and you can take whatever portions of the code you need.

You will find a JUnit3 test in the project, called JavaClassFinderTest.java, which shows you the features and usage of the JavaClassFinder class. The only external dependency needed to run the Junit test is Junit.

Basic usage of this utility:

    JavaClassFinder classFinder = new JavaClassFinder();
List<Class<? extends MyTagInterface>> classes = classFinder.findAllMatchingTypes(MyTagInterface.class);

This will give you a List which contains any classes in the classpath which are assignable from the "MyTagInterface.class" (for example). Hope this helps.

Find Java classes implementing an interface

Awhile ago, I put together a package for doing what you want, and more. (I needed it for a utility I was writing). It uses the ASM library. You can use reflection, but ASM turned out to perform better.

I put my package in an open source library I have on my web site. The library is here: http://software.clapper.org/javautil/. You want to start with the with ClassFinder class.

The utility I wrote it for is an RSS reader that I still use every day, so the code does tend to get exercised. I use ClassFinder to support a plug-in API in the RSS reader; on startup, it looks in a couple directory trees for jars and class files containing classes that implement a certain interface. It's a lot faster than you might expect.

The library is BSD-licensed, so you can safely bundle it with your code. Source is available.

If that's useful to you, help yourself.

Update: If you're using Scala, you might find this library to be more Scala-friendly.

How get list of all classes that inherit from the interface with the specified generic (interface<concrete class>)

Your problem can be divided into 2 subproblems:

  1. Getting a list of all classes that implement ICommandHandler
  2. Filtering ones which have a required type parameter

As @ArvindKumarAvinash said, you can find many solutions to the first subproblem here.

And here is my solution for a second one:

public static <T extends ICommand> List<Class<? extends ICommandHandler<T>>> getCommandHandlers(
Class<T> commandClass, String packageName
) {
return new Reflections(packageName).getSubTypesOf(ICommandHandler.class).stream()
.filter(subtype -> !subtype.isInterface())
.filter(subtype -> Objects.equals(getParameter(subtype, ICommandHandler.class, 0), commandClass))
.map(subtype -> (Class<? extends ICommandHandler<T>>) subtype)
.collect(Collectors.toList());
}


@Nullable
public static <T> Type getParameter(
Class<T> clazz,
Class<? super T> parametrizedParent,
int index
) {
Type result = null;
for (ParameterizedType parent : getParameterizedParents(clazz, parametrizedParent)) {
result = parent.getActualTypeArguments()[index];
if (!(result instanceof TypeVariable)) return result;
index = getTypeVariableIndex((TypeVariable<?>) result);
}
return result;
}

private static <T> List<ParameterizedType> getParameterizedParents(Class<? extends T> clazz, Class<T> parent) {
List<ParameterizedType> genericParents = new ArrayList<>();
Class<? extends T> current = clazz;
while (true) {
Type supertype = getSuperType(current, parent);
if (supertype instanceof ParameterizedType)
genericParents.add((ParameterizedType) supertype);
else genericParents.clear();
Type rawSupertype = toRawType(supertype);
if (rawSupertype == parent) {
Collections.reverse(genericParents);
return genericParents;
}
current = (Class<? extends T>) rawSupertype;
}
}

private static <T> Type getSuperType(Class<? extends T> child, Class<T> parent) {
if (child == parent) return child;
Type superclass = child.getGenericSuperclass();
if (isSubTypeOfClass(superclass, parent)) return superclass;
for (Type type : child.getGenericInterfaces())
if (isSubTypeOfClass(type, parent)) return type;
throw new IllegalArgumentException(child.getName() + " is not assignable from " + parent.getName());
}

private static int getTypeVariableIndex(final TypeVariable<?> typeVariable) {
return Arrays.asList(typeVariable.getGenericDeclaration().getTypeParameters()).indexOf(typeVariable);
}

private static boolean isSubTypeOfClass(Type type, Class<?> clazz) {
Type rawType = toRawType(type);
return rawType instanceof Class && clazz.isAssignableFrom((Class<?>) rawType);
}

private static Type toRawType(Type type) {
return type instanceof ParameterizedType ? ((ParameterizedType) type).getRawType() : type;
}

Is it possible to get all classes that implementing an interface?

There's no 100% reliable way to do what you want. The reason is because of how class loading works in Java.

Classes, in Java, are loaded "on demand". The first time a class is referenced in code (either statically or dynamically), the JVM will use the current class loader and try to load it. A ClassLoader has no method that gives all the classes that could be loaded from it, therefore you cannot iterate on classes.

There are some unreliable workarounds. For instance, if you know your ClassLoader will only ever load classes from inside a specific directory, or a specific JAR file, you can then use the classes related to your file system to find what ".class" files are available, then you can load everything (which takes time and will consume a lot of your PermGen, which might be a problem -- remember that you cannot easily unload a class! (unless you do some ClassLoader magic)), and use reflection to filter the classes implementing your interface.

The problem with this workaround is that it will most probably stop working if you ever change your deployment. For instance, if you start deploying a JAR file, then later on you decide to use a servlet container that will deal with WAR files, your code might not work anymore.

If you really want to try this approach, there's a project called Reflections that might be useful.

The most reliable way I've ever implemented this is by using an Annotation Processor. You write an annotation, you annotate your interface, and you write some code that will get executed by the compiler, in compile-time, that will collect the classes implementing your interface and save their names in a resource file. Then you write a class with a method that reads that file and gives you a Class object for each class name listed in that resource file.

The problem with this approach is that only classes that are compiled in my build process will get listed (ie, if you publish a library with an interface and expect others to implement your interface, this approach won't be useful, since your code will never know about the class in others' projects). If this is enough for you, as it was for me, this solution works flawlessly. I can use it in Servlet Containers with WAR (exploded or not) deployments, in executable jars, whatever. It will always work.

Finding specific implementation of generic interface on classpath

You can add a method to your Room definition (interface or abstract class) which provides an appropriate cleaner for you. Since you need to add a Cleaner when you add a room, there's no additional configuration.

public interface Room {
Cleaner<? extends Room> cleanerInstance();
}

public class Bathroom implements Room {
public Cleaner<Bathroom> cleanerInstance(){
return new BathroomCleaner();
}
}

If you want to find it without the Room being aware, you'll need some sort sort of configuration or lookup.



Related Topics



Leave a reply



Submit