atteo / classindex

Index classes, do not scan them!
Apache License 2.0
263 stars 43 forks source link

Is it intended not to index anon classes? #39

Open twwwt opened 7 years ago

twwwt commented 7 years ago

Consider the following example

@IndexSubclasses
public interface I { /* ... */ }

public interface J extends I { /* ... */ }

public class SomeClass
{
   public static final J j = new J() { /* ... */ }; // Anon implementation of J.
}

I would expect that the anon class (which compiles to a class file name SomeClass$1, disregarding the package name) would be included in the index of the interface I. However, a test showed that this is not the case, which brings me to the question whether this is intended?

sentinelt commented 6 years ago

Actually this is intended. I think in most of the cases its not what the user of the library would expect. Such a feature could be added with a (disabled by default) configuration option though.

twwwt commented 6 years ago

Adding a configuration option would be great, perhaps something like @IndexSubclasses(includeAnonClasses = true).

sentinelt commented 6 years ago

@twwwt I'm trying to understand the purpose of such an index. I don't see how it can be useful to have an index of anonymous classes, because they have exactly one instance and it is hidden inside some class or method. What is your use case?

twwwt commented 6 years ago

@sentinelt Consider the following class hierarchy

@IndexSubclasses
public interface Indexed { /* ... */ }

public class SomeClass {
   public static final Indexed SOME_CONSTANT = new Indexed() {
      // Anon class with some logic inside.
   };
}

public interface SubIndexed extends Indexed {
   public static final SubIndexed ANOTHER_CONSTANT = new SubIndexed() {
      // Anon class with some logic inside.
   };
}

public enum EnumIndexed implements Indexed {
   one, two, three;
}

We want to find the constants implementing Indexed. This is possible for ANOTHER_CONSTANT and the enum values in EnumIndexed because SubIndexed and EnumIndexed are contained in the index built for Indexed. However, since the anon class defined for SOME_CONSTANT is not part of the index, we have no chance to find that constant (at least not by means of the index created by Classindex). If that anon class would be part of the index, we could call getEnclosinglass() on it thereby getting SomeClass.class, on which we could then call getDeclaredFields() and filter those that are assignable from Indexed (and whose modifier is public and static).