首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Java Morphia Map/List基于泛型类型加载,但不从继承给定类型的子类加载

基础概念

Morphia 是一个用于 MongoDB 的 Java ORM(对象关系映射)库,它允许开发者将 Java 对象映射到 MongoDB 文档中,并提供了方便的 API 来进行数据库操作。在 Morphia 中,MapList 是常用的数据结构,它们可以用来存储和操作嵌套的文档数据。

相关优势

  1. 简化开发:Morphia 通过自动映射 Java 对象到 MongoDB 文档,减少了手动编写 CRUD 操作的代码量。
  2. 类型安全:使用泛型可以确保在编译时检查类型,减少运行时错误。
  3. 灵活性:Morphia 支持复杂的嵌套结构和自定义类型转换器,使得数据模型更加灵活。

类型

  • Map:键值对集合,键通常是字符串,值可以是任意类型。
  • List:有序集合,可以存储多个相同类型的元素。

应用场景

  • 数据存储:将 Java 对象持久化到 MongoDB 数据库中。
  • 数据查询:通过 Morphia 提供的 API 进行复杂的数据查询和聚合操作。
  • 数据转换:在 Java 对象和 MongoDB 文档之间进行自动转换。

问题描述

在使用 Morphia 时,可能会遇到一个问题:基于泛型类型加载 MapList,但不从继承给定类型的子类加载。这意味着如果你有一个基类和一个子类,Morphia 只会加载基类的 MapList,而不会加载子类的。

原因

这个问题通常是由于 Morphia 的类型擦除机制导致的。Java 的泛型在编译时会进行类型擦除,这意味着在运行时,Morphia 无法获取到具体的泛型类型信息,只能获取到原始类型。

解决方法

  1. 使用注解:通过 @Property@Type 注解来明确指定泛型的具体类型。
代码语言:txt
复制
@Entity
public class MyClass {
    @Property("myMap")
    private Map<String, MySubClass> myMap;

    // getters and setters
}
  1. 自定义类型转换器:实现 TypeConverter 接口来自定义类型转换逻辑。
代码语言:txt
复制
public class MySubClassConverter extends TypeConverter<MySubClass> {
    @Override
    public MySubClass decode(Class<?> targetClass, Object fromDBObject, MappedField optionalExtraInfo) {
        // 自定义解码逻辑
    }

    @Override
    public Object encode(MySubClass value, MappedField optionalExtraInfo) {
        // 自定义编码逻辑
    }
}

然后在 Morphia 中注册这个转换器:

代码语言:txt
复制
Datastore datastore = morphia.createDatastore(new MongoClient(), "database");
datastore.getMapper().getConverters().addConverter(new MySubClassConverter());
  1. 使用具体类型:尽量避免使用泛型,而是使用具体的类型。
代码语言:txt
复制
@Entity
public class MyClass {
    private Map<String, MySubClass> myMap;

    // getters and setters
}

参考链接

通过以上方法,可以解决 Morphia 在加载 MapList 时无法从继承给定类型的子类加载的问题。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

3小时Java入门

多态具有一个非常强大的功能,就是允许添加更多类型的子类实现功能扩展,却不需要修改基于父类的代码。 这就实现了面向对象编程非常著名的开闭原则:对扩展开放,对修改封闭。 ? ? ?...5,获取继承关系 ? ? 二十五,泛型 泛型就是编写模板代码来适应任意类型。Java的容器类中大量使用了泛型。 泛型的好处是使用时不必对类型进行强制转换,它通过编译器对类型进行检查。...Java中泛型的实现是使用的擦拭法,编译器编译包含泛型的类时将泛型换成Object类型, 编译器编译泛型实例化的代码时根据泛型的具体类型进行安全转型,而JVM虚拟机对泛型一无所知。...因此泛型的类型不能是int,float,double等基本类型,并且不能够获取泛型的反射。 ? ?...Java中用尖括号来表示泛型,Scala中用方括号来表示泛型。 Java中的数组用花括号来表示,Scala中一般用工厂方法。

2.7K30

Java基础

集合相关问题List,Set,Queue,Map四种集合的特点和区别在 Java 中,List、Set、Queue 和 Map 是常用的集合接口,它们各自具有不同的特点和用途:List(列表):允许重复元素...Java泛型泛型的含义泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数适用场景:写一个排序方法,能够对整型数组、字符串数组甚至其他任何类型的数组进行排序,该如何实现?...答案是:可以使用 Java 泛型。使用 Java 泛型的概念,我们可以写一个泛型方法来对一个对象数组排序。然后,调用该泛型方法来对整型数组、浮点数数组、字符串数组等进行排序。...extends Number>来定义,如此定义就是通配符泛型值接受Number及其下层子类类型类型通配符下限通过形如 List的对象上使用相同的方法名,但根据对象的实际类型,可以产生不同的行为方法重写(Override):多态性基于方法的重写。子类可以根据自身的需求重写(覆盖)父类的方法。

23020
  • Retrofit解析3之反射

    例如,Mapl类允许您向一个Map 添加任意类的对象,即使最常见的情况是在给定映射(map)中保存某个特定类型(比如 String) 的对象。...在生成的Java字节码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数,会被编译器在编译的时候去掉。这个过程就叫做类型擦除。...来表示位置类型,比如List就声明了List中包含的元素类型是未知的。通配符所代表的其实是一组类型,但具体的类型是未知的。List 所声明的就是所有类型都是可以的。但是List类型未知,但肯定是Object及其子类。 (六) 泛型的使用注意事项: 在使用泛型的时候可以遵循一些基本的原则,从而避免一些常见的问题。 在代码中避免泛型类和原始类型的混用。...(七) 泛型与反射 1、Java泛型与反射结构 java中class,method,field的继承体系 ? Paste_Image.png java中所有对象的类型定义类Type ?

    1.2K20

    java核心技术第六篇之断言、日志、包装类型和工具类

    8 泛型简化,出现菱形泛型 9 异常的多个catch合并,每个异常用或| 10 try-with-resources 语句 JDK1.8 新特性: 一、接口的默认方法:Java 8允许我们给接口添加一个非抽象的方法实现...接口与多继承 1. 可以让子类继承主要类型,让次要类型作为一个接口让子类实现. 2. 单继承具备简单性(相对于多继承),使用接口实现的多继承并不会破坏其简单性 2....Set的泛型需要注意写法: 例: SetMap.Entry> set = map.entrySet(); 键值对的类型为:Map.Entry , 例...类型 ↑↑以上是JDK5.0之前泛型没出的时候的做法 加泛型之后,不需要在强转了 2....Properties限定泛型,只能装String类型数据(name,value) 4.

    85710

    Java JDK1.5: 泛型 新特性的讲解说明

    泛型在继承上的体现关于父类中含有泛型 对应的子类的对父类泛型的处理情况:如下父类有泛型,子类继承父类:不保留父类中的泛型,擦除了父类中的泛型(默认是 Object)// 父类class Father...父类有泛型,子类继承父类:并指明了父类的泛型(具体类型) 注意: 由于子类在继承泛型的父类/实现的接口时,指明了泛型具体是什么类型,所以实例化子类对象时,不再需要指明泛型了。...}父类有泛型,子类继承父类:并保留了父类的泛型(并没有指明具体类型)注意: 因为子类并没有指明父类泛型的具体类型,所以子类要沿用上父类的泛型从而对父类上的泛型(赋予具体类型),不然编译无法通过。...Father { }父类有泛型,子类继承父类:并保留了父类的部分泛型(部分指明了父类的泛型具体类型,部分没有指明父类的泛型具体类型),外加子类定义自己独有的泛型注意: 因为子类并没有指明父类泛型的具体类型...// 父类class Father {}// 父类有泛型,子类继承父类:并保留了父类的`部分`泛型(部分指明了父类的泛型具体类型,部分没有指明父类的泛型具体类型),外加子类定义自己独有的泛型

    95000

    JavaSE笔记

    : 将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型 这种参数类型可以用在类、方法、和接口中,分别被称为泛型类、泛型方法、泛型接口 泛型定义格式 类型>:指定一种类型的格式,这里的类型可以看成是形参...这里的类型可以看成是形参 将来具体调用时候给定的类型可以看成是实参,并且实参的类型只能是引用类型数据 泛型类定义格式 修饰符 class 类名 类型>{}; 泛型方法定义格式 修饰符 类型> 返回值类型...方法名(类型 变量名){} 泛型接口定义格式 修饰符 interface 接口名类型>{} 类型通配符 为了表示各种泛型List的父类,可以使用通配符 类型通配符: List:表示元素类型未知的List,它的元素可以匹配任何的类型 这种通配符的List仅表示它是各种泛型List的父类,并不能把元素添加到其中 类型通配符上限:的泛型是什么类型,那么接口中的get()方法就会生产什么类型的数据提供我们使用 Consumer接口 Consumer :包含两个方法 void accept(T t):对给定的参数执行操作

    1.3K21

    Java学习的知识笔记

    final类不能被继承,即不能有子类,final方法不能被子类重写 19 list结合子类特点: Arraylist:底层数据结构是数组,查询速度快,增删速度慢 有序,可重复 linkedList...参考enumerable.java 24 hashmap 25 泛型 对于不同类型的对象进行同一事件的解决。比如说人和熊猫都要吃饭,人是一顿,熊猫是多少根竹子。...参考thing.java,泛型定义单词不一样。 26 序列化,反序列化 前者将对象转换成字节流,后者将字节流换成对象,子类也可以进行序列化,对于静态属性字段不可以序列化,它不是对象。...返回一个组合的Consumer。一次执行此操作,然后进行after操作,泛型接口,两次连续操作只公用原始的的数据。...不会套接上一个消费之后的数据 3 Supplier接口 泛型接口 boolean test(T t)对给定的参数进行判断,判断逻辑有lanmbda表达式实现,返回一个布尔值。

    8210

    Java基础八股文(背诵版)

    多重继承会使类型转换、构造方法的调用顺序变得复杂,会影响到性能。 简述 Java 的多态 Java 多态可以分为编译时多态和运行时多态。...简述 Object 类常用方法 hashCode:通过对象计算出的散列码。用于 map 型或 equals 方法。需要保证同一个对象多次调用该方法,总返回相同的整型值。...当垃圾回收器准备好释放对象占用空间时,首先会调用 finalize()方法,并在下一次垃圾回收动作发生时真正回收对象占用的内存。 简述泛型 泛型,即“参数化类型”,解决不确定对象具体类型的问题。...在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型在类中称为泛型类、接口中称为泛型接口和方法中称为泛型方法。...简述泛型擦除 Java 编译器生成的字节码是不包涵泛型信息的,泛型类型信息将在编译处理是被擦除,这个过程被称为泛型擦除。 简述注解 Java 注解用于为 Java 代码提供元数据。

    45K2738

    精选Java基础面试120题

    2.20 请简述泛型是什么?有什么用?在哪里用? 泛型是什么?泛型是一种特殊的类型,它把指定类型的工作推迟到客户端代码声明并实例化类或方法的使用进行。...泛型的好处 提高了程序的安全性 将运行期遇到的问题转移到了编译期 省去了类型强转的麻烦 泛型的常见应用 泛型类 泛型方法 泛型接口 2.21 如何编写一个泛型方法,让它能够接受泛型参数并返回泛型类型?...并举例 泛型方法,指把泛型定义在方法上,使用泛型类型来替代原始类型 public static T[] sort(T[] t){ Arrays.sort(t); return t; } 2.22...请简述Java中如何使用泛型编写带有参数的类?...extends T :代表接收的泛型类型为T类型或T子类类型 List向上限制? super T :代表接收的泛型类型为T类型或T父类类型 7.9 请简述Set集合的特点?

    78720

    java泛型中的通配符 T,E,K,V,?

    若文章内的图片失效(无法正常加载),请留言反馈或直接联系我。...java泛型 java泛型(generics)是jdk5引入的新特性,泛型提供了编译时类型安全检测机制,该机制运行开发者在编译时检测到非法的类型....泛型的本质是参数化类型,也就是说,将所操作的数据类型作为一个参数传递,通过这个类型参数,就能识别这个变量的类型 public class TestGeneric { private T...K和V 表示key,value,比如用于map的通配符 T(type) 表示具体的一个java类型 E (element) 表示一个元素,例如List 除了这几个特定意义的通配符之外,还存在 ?...super E> 下界: 用 super 进行声明,表示参数化的类型可能是所指定的类型,或者是此类型的父类型,直至 Object private void test(List<?

    68610

    Java基础题

    1、JAVA中的几种基本数据类型是什么,各自占用多少字节。 ? 2、String类能被继承吗,为什么 不能。...25、在jdk1.5中,引入了泛型,泛型的存在是用来解决什么问题。...面向对象的转型只会发生在具有继承关系的父子类中(接口也是继承的一种) 向上转型:其核心目的在于参数的统一上,根本不需要强制类型转换。...不过呢,在JDK1.5之后,新增加了泛型的技术,这就将上述向下转型的问题消灭在了萌芽之中。...泛型的核心意义在于:类在进行定义的时候可以使用一个标记,此标记就表示类中属性或者方法以及参数的类型,标记在使用的时候,才会去动态的设置类型。 26、Java中的HashSet内部是如何工作的。

    1K10

    Q&A:Java

    在Java语言中,多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定, 在Java中实现多态的三个必要条件:继承、重写、向上转型。...泛型 泛型提供编译时类型安全检测机制,通过泛型参数可以指定传入的对象类型,编译时可以对泛型参数进行检测 泛型擦除:泛型信息只存在于代码编译阶段,在进入 JVM 之前,与泛型相关的信息会被擦除掉。...Java编译器是通过先检查代码中泛型的类型,然后在进行类型擦除,再进行编译。 编译时,检查添加元素的类型,更安全,减少了类型转换次数,提高效率。...比如原生的List返回类型是Object对象,需要手动转换类型才能使用,使用泛型后编译器自动转换 泛型类、泛型接口、泛型方法 支持通配符 :支持任意泛型类型 :支持A类以及A类的子类,规定了泛型的上限 <?

    63120

    记录(三)

    具体可以看以前转的一篇文章:关于一次List的面试 之前写过的ArrayList相关内容:ArrayList的扩容机制 1.4 讲讲类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数...代码验证可以看这个:Java基础-类的实例化顺序 1.5 用过哪些 Map 类,都有什么区别,HashMap 是线程安全的吗,并发下使用的 Map是什么,他们内部原理分别是什么,比如存储方式,hashcode...LinkedHashmap是基于链表来实现数据插入有序的。 1.8 抽象类和接口的区别,类可以继承多个类么,接口可以继承多个接口么,类可以实现多个接口么。...继承 指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力,继承是类与类或者接口与接口之间最常见的关系;在Java中此类关系通过关键字extends...3.6 在 jdk1.5 中,引入了泛型,泛型的存在是用来解决什么问题。 泛型主要针对向下转型时所带来的安全隐患,其核心组成是在声明类或接口时,不设置参数或属性的类型。

    40910

    Java基础-甲骨文系列

    简述泛型 泛型,即“参数化类型”,解决不确定对象具体类型的问题。在编译阶段有效。...在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型在类中称为泛型类、接口中称为泛型接口和方法中称为泛型方法。...简述泛型擦除 Java编译器生成的字节码是不包涵泛型信息的,泛型类型信息将在编译处理时被擦除,这个过程被称为泛型擦除。...动态代理实现方式 包括两种方式:基于接口的继承和基于类的继承 利用JDK反射机制,实现代理接口。 利用CGLib,对指定类生成子类,进行代理。...Java集Collection类型 链表List:ArrayList, Vector, LinkedList 集合Set:Hashset, LinkedHashSet, TreeSet 表Map:HashMap

    84710

    Java基础(二十):泛型

    不能使用基本数据类型,此时只能使用包装类替换 除创建泛型类对象外,子类继承泛型类时、实现类实现泛型接口时,也可以确定泛型结构中的泛型参数 如果我们在给泛型类提供子类时,子类也不确定泛型的类型,则可以继续使用泛型参数...接口上声明的泛型,在本类或本接口中即代表某种类型,但不可以在静态方法中使用类的泛型 静态方法需要在类加载初始化默认值,类泛型在创建对象时候才能确定类型,所以自洽 异常类不能是带泛型的 举例1: class...如果B是A的一个子类型(子类或者子接口) 而G是具有泛型声明的类或接口 G并不是G的子类型!...为泛型非限定通配符,表示类型未知,不用声明,可以匹配任意的类 比如:List,Map List:允许使用的类型必须是指定类/接口,或继承指定类、实现指定接口,即(子类)<= 通配符指定下限:<?

    13810

    Kotlin入门潜修之类和对象篇—泛型及其原理

    因为map2的值只能是Integer,所以返回的是Integer,而不是String } java中既支持类泛型也支持方法泛型。...无界通配符可以接受任意类型赋值;子类限定通配符可以接受泛型类型为其子类、本身或者没有泛型类型的赋值,其中没有泛型类型赋值时会有编译警告。...所谓协变就是只要参数类型具有继承关系就认为整个泛型类型也有“继承”关系:比如上例中,String继承于Any,那么我们就可以认为IList是IList的子类型,这样就可以让IList...in修饰符允许我们写 } 这种情况叫做逆变,即我们当类型参数具有继承关系的时候,我们可以认为整个泛型也有继承关系,而使用in修饰后,可以允许父类型变量赋值于子类型变量,如上面代码中,将Comparable...threshold }.map { it.toString() } } 泛型原理 kotlin中的泛型同java一样,都是“假”泛型,为什么这么说?

    93930

    Java高级特性入门——泛型、反射和注解!

    一言以蔽之,泛型就是通过类型参数化,来解决程序的通用性设计和实现的若干问题。 Java泛型是1.5版本后引入的特性,它主要被用于解决三类问题: 1、编译器类型检查 ?...乍一看类型变量这个词,感觉有点晦涩难懂,但其实如果仔细思量一番会发现它其实并不难理解,上面的实例4可以理解为“在使用泛型时,可以将类型参数T传递给Box类型本身”,结合Oracle给出的官方定义“泛型的本质是类型参数化...对于实例3,如果不使用泛型,当一个不清楚业务场景的人在对集合进行操作时,无法知道list中存储的是什么类型的对象,如果使用了泛型,就能够通过其类型参数判断出当前的业务场景,也增加了代码的可读性,同时也可以大胆地在抽象继承的基础上进行开发了...通配符的设计存在一定的场景,例如在使用泛型后,首先声明了一个Animal的类,而后声明了一个继承自Animal类的Cat类,显然Cat类是Animal类的子类,但是List却不是List的子类型,而在程序中往往需要表达这样的逻辑关系...如上图中的第一个例子,第三个add()操作会受限,原因在于List和List是List的子类型。

    1K30

    一文打通java泛型

    从JDK1.5以后,Java引入了“参数化类型(Parameterized type)”的概念, 允许我们在创建集合时再指定集合元素的类型,正如:List,这表明 该List只能保存字符串类型的对象。...12.父类有泛型,子类可以选择保留泛型也可以选择指定泛型类型: 子类不保留父类的泛型:按需实现 class Father { } 没有类型 擦除 // 子类不保留父类的泛型 // 1...(子类或者子接口),而G是具有泛型声明的 类或接口,G并不是G的子类型!...比如:String是Object的子类,但是List并不是List的子类。  通配符的使用 基本介绍 1.使用类型通配符:? 比如:List ,Map Lis泛型的引用调用 通配符指定上限 上限extends:使用时指定的类型必须是继承某个类,或者实现某个接口,即<= 通配符指定下限 下限super:使用时指定的类型不能小于操作的类,即>

    18230

    详解Gson的TypeToken原理

    泛型擦除 众所周知,Java的泛型只在编译时有效,到了运行时这个泛型类型就会被擦除掉,即List和List在运行时其实都是List类型。...Java的类库是Java生态中非常宝贵的财富,必须保证向后兼容(即现有的代码和类文件依旧合法)和迁移兼容(泛化的代码和非泛化的代码可互相调用)基于上面这两个背景和考虑,Java设计者采取了"类型擦除"这种折中的实现方式...正如上面说的,如果直接把ListMap>的类型传过去,但是因为运行时泛型被擦除了,所以得到的其实是List,那么后面的Gson就不知道要转成MapJava语法中,在这个语境,{}是用来定义匿名类,这个匿名类是继承了TypeToken类,它是TypeToken的子类。 为什么要通过子类来获取泛型的类型?...ParameterizedType是表示带有泛型参数的类型的Java类型,JDK1.5引入了泛型之 后,Java中所有的Class都实现了Type接口,ParameterizedType则是继承了Type

    5.7K22
    领券