为了账号安全,请及时绑定邮箱和手机立即绑定

是否可以将引用类型传递给需要动态引用类型的对象实例?

是否可以将引用类型传递给需要动态引用类型的对象实例?

阿波罗的战车 2022-07-14 10:08:42
例如: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; 
查看完整描述

3 回答

?
慕尼黑5688855

TA贡献1848条经验 获得超2个赞

假设您有以下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有 oneFerrari和 one的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's 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!"

}


查看完整回答
反对 回复 2022-07-14
?
人到中年有点甜

TA贡献1895条经验 获得超7个赞

处理这个问题的正确方法是让两个类(例如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通过传入一个代表 a 的类来实例化 a 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();

        }

    }

}


查看完整回答
反对 回复 2022-07-14
?
qq_笑_17

TA贡献1818条经验 获得超7个赞

是的,您可以使用泛型。


  public <T> void builCarManager(T car) {

    Manager<T> carManager = new Manager<>();

 }

现在您可以传递任何类型的对象。创建的管理器将属于同一类型。


查看完整回答
反对 回复 2022-07-14
  • 3 回答
  • 0 关注
  • 103 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信