例如:
public void builCarManager(Car car) {
Manager<car.getClass()> carManager = new Manager<>();
}
有人建议解决这个问题吗?
编辑
我的主要问题是:
public class CustomSerializer<T> extends StdSerializer<T> {
@Override
public void serialize(T car, JsonGenerator gen, SerializerProvider sp) {
// I get car.getClass() fine but I need add it
Manager<T> carManager = new Manager<>();
// Manager<car.getClass()> carManager = new Manager<>();
}
}
在这里,我无法通过CustomSerializer<Lamborgini>.class
。
@JsonSerialize(using = CustomSerializer.class)
private Lamborgini car;
让我们假设你有以下POJO
模型:
class Car {
}
class Lamborghini extends Car {
}
class Ferrari extends Car {
}
你的Manager
课程如下所示:
class Manager<T extends Car> {
private Class<T> clazz;
public Manager(Class<T> clazz) {
this.clazz = clazz;
}
public String generateCustomCarName() {
if (Lamborghini.class == clazz) {
return "Lambooooo!";
} else if (Ferrari.class == clazz) {
return "Wild horse Ferrari!";
}
return "Not for everyone!";
}
@Override
public String toString() {
return String.format("Manager[clazz=%s]", clazz.getName());
}
}
现在,让我们创建一个Store
,其中有一个Ferrari
和一个Lamborghini
:
class Store {
private Car ferrari = new Ferrari();
private Car lamborghini = new Lamborghini();
public Car getFerrari() {
return ferrari;
}
public void setFerrari(Car ferrari) {
this.ferrari = ferrari;
}
public Car getLamborghini() {
return lamborghini;
}
public void setLamborghini(Car lamborghini) {
this.lamborghini = lamborghini;
}
}
现在,我们需要在运行时获得class
信息。因为Java
的Type Erasure我们需要提供class
:
class CustomCarSerializer<T extends Car> extends StdSerializer<T> {
public CustomCarSerializer(Class<T> clazz) {
super(clazz);
}
@Override
public void serialize(T value, JsonGenerator jgen, SerializerProvider provider)
throws IOException {
Manager<T> manager = new Manager<>(_handledType);
jgen.writeString(manager.generateCustomCarName());
}
}
请注意,StdSerializer
也有需要class
的构造函数,我们稍后可以使用_handledType
读取它。现在我们需要使用SimpleModule
配置使用序列化器的实现:
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import java.io.IOException;
public class Cars {
public static void main(String[] args) throws Exception {
SimpleModule carsModule = new SimpleModule("CarsModule");
carsModule.addSerializer(Lamborghini.class, new CustomCarSerializer<>(Lamborghini.class));
carsModule.addSerializer(Ferrari.class, new CustomCarSerializer<>(Ferrari.class));
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(carsModule);
mapper.enable(SerializationFeature.INDENT_OUTPUT);
System.out.println(mapper.writeValueAsString(new Store()));
}
}
上面的代码打印:
{
"ferrari" : "Wild horse Ferrari!",
"lamborghini" : "Lambooooo!"
}
处理这个的正确方法是让两个类(例如Car
和Desk
)实现一个公共接口(例如Item
)并将该接口与Manager
类相关联。
public class Instance {
private static interface Item {
String getName();
}
private static class Car implements Item {
@Override
public String getName() {
return "Car";
}
}
private static class Desk implements Item {
@Override
public String getName() {
return "Desk";
}
}
private static class Manager<T extends Item> {
private T item;
public Manager(T item) {
this.item = item;
}
@Override
public String toString() {
return String.format("Manager[item=%s]", item.getName());
}
}
public static <E extends Item> Manager<E> buildItemManager(E item) {
return new Manager<E>(item);
}
public static void main(String[] args) {
Item car = new Car(), desk = new Desk();
Manager<Item> manager1 = buildItemManager(car);
System.out.println(manager1);
Manager<Item> manager2 = buildItemManager(desk);
System.out.println(manager2);
}
}
Manager[item=Car]
Manager[item=Desk]
另一种观点......通过传递代表Manager
的类来实例化Item
。
public class Instance {
public static interface Item {
String getName();
}
public static class Car implements Item {
@Override
public String getName() {
return "Car";
}
}
public static class Desk implements Item {
@Override
public String getName() {
return "Desk";
}
}
public static class Manager<T extends Item> {
private T item;
public Manager(T item) {
this.item = item;
}
@Override
public String toString() {
return String.format("Manager[item=%s]", item.getName());
}
}
public static <E extends Item> Manager<E> buildItemManager(Class<E> item) throws InstantiationException, IllegalAccessException {
return new Manager<E>(item.newInstance());
}
public static void main(String[] args) {
try {
/* Cannot initialize array with generic types... */
@SuppressWarnings("unchecked")
Manager<? extends Item>[] managers = new Manager[2];
managers[0] = buildItemManager(Car.class);
managers[1] = buildItemManager(Desk.class);
for (Manager<?> manager : managers) {
System.out.println(manager);
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
是的,你可以使用泛型。
public <T> void builCarManager(T car) {
Manager<T> carManager = new Manager<>();
}
现在您可以传递任何类型的对象。创建的经理将属于同一类型。