In my library Transfuse I use a code generator to build a handful of classes that look up resources. Each of these look up classes are proxied by a static utility class so they may be referenced before the generated class is built. For instance, the Parcels
class can be used to wrap an object with a generated Parcelable
class:
ExampleParcel parcel = new ExampleParcel();
Parcelable parcelable = Parcels.wrap(parcel);
// ... load into bundle as extra, etc
Parcels
proxies a generated class called Transfuse$Parcels
.
Parcels
:
public final class Parcels {
public static final String PARCELS_NAME = "Parcels";
public static final String PARCELS_REPOSITORY_NAME = "Transfuse$Parcels";
public static final String PARCELS_PACKAGE = "org.androidtransfuse";
private static ParcelRepository instance;
static{
try{
Class injectorClass = Class.forName(PARCELS_PACKAGE + "." + PARCELS_REPOSITORY_NAME);
instance = (ParcelRepository) injectorClass.newInstance();
} catch (ClassNotFoundException e) {
instance = null;
} catch (InstantiationException e) {
throw new TransfuseRuntimeException("Unable to instantiate generated ParcelRepository", e);
} catch (IllegalAccessException e) {
throw new TransfuseRuntimeException("Unable to access generated ParcelRepository", e);
}
}
private Parcels(){
// private utility class constructor
}
public static Parcelable wrap(Object input) {
if(instance == null){
throw new TransfuseRuntimeException("Unable to find " + PARCELS_REPOSITORY_NAME + " class");
}
return instance.wrap(input);
}
}
Transfuse$Parcels
:
@Generated(value = "org.androidtransfuse.TransfuseAnnotationProcessor", date = "01/12/2013 16:56:02 MST")
public class Transfuse$Parcels
implements ParcelRepository
{
private final Map<Class, ParcelableFactory> parcelWrappers = new HashMap<Class, ParcelableFactory>();
public Transfuse$Parcels() {
parcelWrappers.put(...);
}
@Override
public Parcelable wrap(Object input) {
return parcelWrappers.get(input.getClass()).buildParcelable(input);
}
// Define ParcelableFactory classes...
}
Is this technique of loading the generated class using the static initialization block optimal? As you can see, if the class is not found (not generated possibly) then the ParcelRepository
instance ends up being null
and wrap()
would always return null
. Should wrap()
throw a runtime exception if an instance is not found instead?
If you take a look at the library, the code above is a simplification for example purposes: Parcels
Parcels
andTransfuse$Parcels
can not be in the samejar
? \$\endgroup\$