简体   繁体   中英

Avoid repeating type names for generic functions that take a Class/GenericType param

Given functions such as the following using GenericType , or even just Class<T> , which I often see with serialization code (JSON, XML, etc.), is it possible to write it in such a way that I do not have to write the full (and sometimes long) type multiple times?

eg like the Java diamond operator when creating collections, or the C++ 11 auto keyword. Or even just a C style typedef style solution (so I can create a shorter name, maybe by using a null initialized variable instance?).

//What I want to avoid, long "GenericType" parameter
Map<EnterpriseId, List<EnterpriseUser>> usersByEnterprise = Json.readFile(data,
    new GenericType<Map<EnterpriseId, List<EnterpriseUser>>>() { } );

//Creating a container instance
Map<EnterpriseId, List<EnterpriseUser>> usersByEnterprise = new HashMap<>();

You can write:

Map usersByEnterprise = new HashMap();

And use what's called a 'raw type'. This avoids the generic type information but also throws away compile time safety on the map contents. It is probably flagged by your IDE and by Sonar as a code violation, since we generally agree that generic typing is a Good Idea.

Otherwise you are stuck with the generic types, although you could opt for some shorter names, for example:

Map<Id, List<User>> usersByEnterprise = new HashMap<>();

The problem is that you need a (reifiable) subclass to capture the actual type arguments, but Java 8 strictly specifies the requirement to list the type arguments explicitly for anonymous subclasses. What you can do, is to keep the instantiated type token, which might help, if you need exactly the same type multiple times, eg

static final GenericType<Map<EnterpriseId, List<EnterpriseUser>>> MAP_ID_USER
       = new GenericType<Map<EnterpriseId, List<EnterpriseUser>>>() { };

…

Map<EnterpriseId, List<EnterpriseUser>> usersByEnterprise=Json.readFile(data, MAP_ID_USER);

If you don't like having a static variable floating around, you may recall, that the class doesn't have to be anonymous to serve as type token, eg

public final class MapIdUser extends GenericType<Map<EnterpriseId, List<EnterpriseUser>>> {
}
…

Map<EnterpriseId, List<EnterpriseUser>> usersByEnterprise
                                      = Json.readFile(data, new MapIdUser());

As said, this all helps only, if a particular type occurs multiple times in your project.


That said, not all hope is lost and there's a better future in sight. Java 9 is supposed to lift the restrictions for type inference on anonymous class instantiations. So in Java 9, you'll be able to write:

Map<EnterpriseId, List<EnterpriseUser>> usersByEnterprise
                                      = Json.readFile(data, new GenericType<>() { } );

In current snapshots this is already working…

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM