天道酬勤,学无止境

Issue with declaration of Map<String,Class<? extends Serializable>>

Java provides me by <? extends class> a way of filtering the java classes that you can use to build in this case the new HashMap, for example:

I can do that:

Map<String,? extends Serializable> map1 = new HashMap<String,String>();

It is correct, because String implements Serializable, so the compiler let me do that.

But when i try to do it:

Map<String,GenericClass<? extends Serializable>> map2 = new HashMap<String, GenericClass<String>>();

Being the GenericClass as it:

public class GenericClass<T>
{
.
.
.
}

The compiler throw an error saying:

Type mismatch: cannot convert from HashMap<String,GenericClass<String>> to Map<String,GenericClass<? extends Serializable>>

I would like to know, what is happen?

Maybe the compiler cannot detect the extends class being part of a generic type.

评论

You would need to use the following:

Map<String, ? extends GenericClass<? extends Serializable>> map2 =
        new HashMap<String, GenericClass<String>>();

Nested wildcards are much different from top-level wildcards - only the latter perform wildcard capture. As a result, HashMap<String, GenericClass<String>> is considered inconvertible to Map<String, GenericClass<? extends Serializable>>, because GenericClass<? extends Serializable> is a concrete type argument (and because generics aren't covariant).

See this post for further information on nested wildcards: Multiple wildcards on a generic methods makes Java compiler (and me!) very confused

Map<String,? extends Serializable> map1 = new HashMap<String,String>();

map1 contains an unbounded V that only requires an unknown of Serializable's. Hence it cannot find a generified object to bound this to, except for null.

Map<String,GenericClass<? extends Serializable>> map2 = new HashMap<String, GenericClass<String>>();

The map2 is bounded by a type K (in this case String) and V (Class<? exends Serializable). That's how the Java compiler sees the bounds.

In essence, you cannot put anything in map1 except a null as you will only see map1.put(String key, null value) //Compiler is asking WTF here. Whereas, map2 will, essentially "render" as map2.put(String key, Class<? extends Serializable> value); //Much better....

Because of the bound V in map2, the signature must be the same in its declaration.

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 使用json4s解析JSON时引发非序列化异常(Spark non-serializable exception when parsing JSON with json4s)
    问题 我在尝试解析Spark工作中的json时遇到问题。 我正在使用spark 1.1.0 , json4s和Cassandra Spark Connector 。 抛出的异常是: java.io.NotSerializableException: org.json4s.DefaultFormats 检查DefaultFormats伴随对象以及此堆栈问题,很明显,DefaultFormats无法序列化。 现在的问题是该怎么办。 我可以看到这张票显然已经在火花代码库中通过添加关键字transient解决了该问题,但是我不确定确切如何或在哪里将其应用于我的案例。 解决方案是仅在执行程序上实例化DefaultFormats类,以避免一起进行序列化吗? 人们是否正在使用另一个针对scala / spark的JSON解析库? 我最初尝试单独使用jackson,但遇到了一些我无法轻易解决的注释错误,并且json4s开箱即用。 这是我的代码: import org.json4s._ import org.json4s.jackson.JsonMethods._ implicit val formats = DefaultFormats val count = rdd.map(r => checkUa(r._2, r._1)).reduce((x, y) => x + y)
  • 将JSON序列化器添加到每个模型类?(Add JSON serializer to every model class?)
    问题 在Dart中进行JSON编码时,根据Seth Ladd的鼓励,现在最终批准的正式方式是dart:convert + JSON.Encode 。 假设我们有一堆模型类(PODO),例如: class Customer { int Id; String Name; } 现在,我希望能够像这样对我的域对象进行JSON编码: var customer = new Customer() ..Id = 17 ..Name = "John"; var json = JSON.encode(customer); 不幸的是,这行不通... Uncaught Error: Converting object to an encodable object failed. Stack Trace: #0 _JsonStringifier.stringifyValue (dart:convert/json.dart:416) #1 _JsonStringifier.stringify (dart:convert/json.dart:336) #2 JsonEncoder.convert (dart:convert/json.dart:177) .... ...除非我们明确告诉dart:convert如何编码: class Customer { int Id; String Name; Map
  • Spring Data Mongo存储库::所有Repo问题中的通用共享方法(Spring Data Mongo Repository:: Common shared method across all Repo issue)
    问题 用例 我正在尝试使用将自定义行为添加到Spring Data MongoDB的所有存储库功能中。 该文档无助地描述了如何使用JPA进行连接。 无论如何,获得了与Mongo等效的配置设置。 我想向所有实体添加一个findByCategoryName(String categoryName)方法,因为我所有的实体都将具有Category。 类别是一个DBRef对象,因此必须使用自定义查询。 以下是配置的相关部分 <!-- Activate Spring Data MongoDB repository support --> <mongo:repositories base-package="com.domain.*.repo" repository-impl-postfix="CustomImpl" factory-class="com.domain.commonrepo.CommonMongoRepoFactoryBean"/> <bean id="mappingContext" class="org.springframework.data.mongodb.core.mapping.MongoMappingContext" /> <mongo:mapping-converter mapping-context-ref="mappingContext"> <mongo
  • LambdaConversionException与泛型:JVM错误?(LambdaConversionException with generics: JVM bug?)
    问题 我有一些代码,其中包含方法参考,该参考可以很好地编译并在运行时失败。 唯一的例外是: Caused by: java.lang.invoke.LambdaConversionException: Invalid receiver type class redacted.BasicEntity; not a subtype of implementation type interface redacted.HasImagesEntity at java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:233) at java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:303) at java.lang.invoke.CallSite.makeSite(CallSite.java:289) 触发异常的类: class ImageController<E extends BasicEntity & HasImagesEntity> { void doTheThing(E entity) { Set<String>
  • Spring Data Mongo Repository:: Common shared method across all Repo issue
    Use Case I am trying to use Adding custom behaviour to all repositories functionality of Spring Data MongoDB. The documentation unhelpfully describes how to connect using JPA. Anyways got the config setup with Mongo equivalent. I want to add a findByCategoryName(String categoryName) method to all entities as all my entities will have a Category . Category is a DBRef object so have to use custom query. Below is relevant part of the config <!-- Activate Spring Data MongoDB repository support --> <mongo:repositories base-package="com.domain.*.repo" repository-impl-postfix="CustomImpl" factory
  • 了解上限和下限? 在Java泛型中(Understanding upper and lower bounds on ? in Java Generics)
    问题 我真的很难理解通配符参数。 我对此有一些疑问。 ? 作为类型参数只能在方法中使用。 例如: printAll(MyList<? extends Serializable>)我不能使用?定义类? 作为类型参数。 我了解上限? 。 printAll(MyList<? extends Serializable>)手段:“ printAll将打印MyList如果它具有实施该对象Serialzable接口”。 我对super有一点问题。 printAll(MyList<? super MyClass>)手段:“ printAll将打印MyList如果它具有的对象MyClass或延伸的任何类MyClass (的后代MyClass )”。 纠正我哪里出问题了。 简而言之,仅T或E或K或V或N可用作定义泛型类的类型参数。 ? 只能在方法中使用更新1: public void printAll(MyList<? super MyClass>){ // code code code } 根据Ivor Horton的书MyList<? super MyClass> MyList<? super MyClass>表示如果MyList具有MyClass对象或它实现的任何接口或类,则可以打印MyList 。 也就是说, MyClass是一个下限。 它是继承层次结构中的最后一个类。
  • NotSerializableException与Spark上的json4s(NotSerializableException with json4s on Spark)
    问题 基本上,我必须使用Spark分析HDFS上的一些复杂的JSON。 我使用“ for comprehensions”来(预)过滤JSON和json4s的“ extract”方法,将其包装到case类中 这个很好用! def foo(rdd: RDD[String]) = { case class View(C: String,b: Option[Array[List[String]]], t: Time) case class Time($numberLong: String) implicit val formats = DefaultFormats rdd.map { jsonString => val jsonObj = parse(jsonString) val listsOfView = for { JObject(value) <- jsonObj JField(("v"), JObject(views)) <- value normalized <- views.map(x => (x._2)) } yield normalized } 到现在为止还挺好! 当我尝试将(预)过滤的JSON提取到我的CaseClass时,我得到以下信息: 线程“主”中的异常org.apache.spark.SparkException:由于阶段失败而导致作业中止:任务不可序列化
  • 通过意图传递枚举或对象(最佳解决方案)(Passing enum or object through an intent (the best solution))
    问题 我有一个活动,启动时需要访问两个不同的ArrayList。 这两个列表都是我自己创建的不同对象。 基本上,我需要一种将这些对象从Intent传递到活动的方法。 我可以使用addExtras(),但这需要一个Parceable兼容类。 我可以使我的类可序列化传递,但是据我了解,这会使程序变慢。 我有什么选择? 我可以通过枚举吗? 顺便说一句:有没有一种方法可以将参数从Intent传递给Activity构造函数? 回答1 这是一个古老的问题,但是每个人都没有提到Enum实际上是可Serializable ,因此可以作为额外的东西完美地添加到Intent中。 像这样: public enum AwesomeEnum { SOMETHING, OTHER; } intent.putExtra("AwesomeEnum", AwesomeEnum.SOMETHING); AwesomeEnum result = (AwesomeEnum) intent.getSerializableExtra("AwesomeEnum"); 建议使用静态变量或应用程序范围的变量是一个非常糟糕的主意。 这确实将您的活动与状态管理系统耦合在一起,并且很难维护,调试和解决问题。 备择方案: tedzyc指出了一个很好的观点,即Oderik提供的解决方案会给您带来错误。 但是,提供的替代方法使用起来有些麻ƒ
  • What does it mean: The serializable class does not declare a static final serialVersionUID field? [duplicate]
    This question already has answers here: What is a serialVersionUID and why should I use it? (26 answers) Closed 3 years ago. I have the warning message given in the title. I would like to understand and remove it. I found already some answers on this question but I do not understand these answers because of an overload with technical terms. Is it possible to explain this issue with simple words? P.S. I know what OOP is. I know what is object, class, method, field and instantiation. P.P.S. If somebody needs my code it is here: import java.awt.*; import javax.swing.*; public class
  • Java中的标记接口?(Marker Interfaces in Java?)
    问题 有人告诉我,Java中的Marker接口是一个空接口,用于向编译器或JVM发出信号,必须以特殊方式处理实现此接口的类的对象,例如序列化,克隆等。 但是最近我了解到它实际上与编译器或JVM无关。 例如,对于Serializable接口, ObjectOutputStream writeObject(Object)方法执行类似于instanceOf Serializable以检测该类是否实现Serializable并相应地引发NotSerializableException 。 一切都在代码中处理,这似乎是一种设计模式,所以我认为我们可以定义自己的标记接口。 现在我的疑问: 上面第一点提到的标记接口的定义是否错误? 那么我们如何定义Marker接口呢? 并且为什么不使用instanceOf运算符,为什么不能将方法设为类似writeObject(Serializable)这样的方法,以便进行编译时类型检查而不是运行时检查? 注释比标记接口更好吗? 回答1 上面第一点提到的标记接口的定义是否错误? -在以下部分中是正确的:(1)标记接口必须为空,并且(2)实现该接口意味着要对实现类进行某些特殊处理。 不正确的部分是,这意味着JVM或编译器将以不同的方式对待该类的对象:您正确地观察到是Java类库的代码将这些对象视为可克隆,可序列化等。与编译器或JVM无关。
  • Why does the compiler state no unique maximal instance exists?
    I have the following classes: public class Obj<T> extends BaseModel { public static final String OBJECT = "object"; public Obj(T object) { setObject(object); } public T getObject() { return get(OBJECT); } public void setObject(T object) { set(OBJECT, object); } } And... /** This is a 3rd party library class **/ public class BaseModel implements ModelData, Serializable { //...members and stuff... @SuppressWarnings({"unchecked", "rawtypes"}) public <X> X get(String property) { X obj = null; if (start > -1 && end > -1) { Object o = map.get(property.substring(0, start)); String p = property
  • Java generic field declaration
    In a class without generic types I want to declare a rather complex generic field similar to these: public class Client { private Map<Class<T extends Serializable>, List<Consumer<S extends T>>> classToConsumerTry1; private <T extends Serializable, S extends T> Map<Class<T>, List<Consumer<S>>> classToConsumerTry2; } promblem is the java compiler won't let me :) So my question is how do I correctly introduce T and S without adding types to my class Client. My goal is to enforce the Class being a subtype of Serializable and the Consumer being a subtype of the class you chose for Class.
  • 在运行时(动态)创建简单的POJO类(字节码)(Create simple POJO classes (bytecode) at runtime (dynamically))
    问题 我有以下情况。 我正在编写一些针对数据库运行用户输入的查询并返回结果的工具。 最简单的方法是将结果返回为: List<String[]>但我需要更进一步。 我需要创建(在运行时)一些名称的POJO(或DTO),并为其创建字段,设置器和获取器,并使用返回的数据填充它,然后将其与生成的.class文件一起返回给用户... 所以这里的想法是如何在运行时(动态)创建简单的类(字节码)。我进行了一次基本搜索,发现了许多包含Apache BCEL的库,但是我想我需要更简单的东西... 你对那个怎么想的? 谢谢。 回答1 如果使用CGLib,使用getter和setter创建简单的POJO很容易: public static Class<?> createBeanClass( /* fully qualified class name */ final String className, /* bean properties, name -> type */ final Map<String, Class<?>> properties){ final BeanGenerator beanGenerator = new BeanGenerator(); /* use our own hard coded class name instead of a real naming policy *
  • Java泛型何时需要(When do Java generics require <? extends T> instead of <T> and is there any downside of switching?)
    问题 给定以下示例(将JUnit与Hamcrest匹配器一起使用): Map<String, Class<? extends Serializable>> expected = null; Map<String, Class<java.util.Date>> result = null; assertThat(result, is(expected)); 这不能与JUnit的assertThat方法签名一起编译: public static <T> void assertThat(T actual, Matcher<T> matcher) 编译器错误消息是: Error:Error:line (102)cannot find symbol method assertThat(java.util.Map<java.lang.String,java.lang.Class<java.util.Date>>, org.hamcrest.Matcher<java.util.Map<java.lang.String,java.lang.Class <? extends java.io.Serializable>>>) 但是,如果我将assertThat方法签名更改为: public static <T> void assertThat(T result, Matcher<? extends T
  • 了解此警告:可序列化类未声明静态最终的serialVersionUID(Understanding this warning: The serializable class does not declare a static final serialVersionUID)
    问题 我有一些静态初始化代码: someMethodThatTakesAHashMap(new HashMap<K, V>() { { put("a","value-a"); put("c","value-c");} }); 由于某种原因,我收到来自Eclipse的警告:可序列化类未声明静态最终的serialVersionUID。 这是在抱怨匿名课吗? 我该怎么办,还是应该压抑它。 回答1 您使用的语法称为双括号初始化-实际上是“实例初始化块,它是匿名内部类的一部分”(一定不是hack)。 因此,使用此表示法时,实际上是在定义一个新的类(!)。 您遇到的“问题”是HashMap实现了Serializable。 该接口没有任何方法,仅用于标识可序列化的语义。 换句话说,它是一个标记器接口,您实际上不需要执行任何操作。 但是,在反序列化期间,Java使用一个称为serialVersionUID的版本号来验证序列化的版本与目标兼容。 如果您不提供此serialVersionUID ,则将对其进行计算。 并且,如Serializable的javadoc中所述,计算值非常敏感,因此建议明确声明该值,以避免任何反序列化问题。 这就是Eclipse所“抱怨”的内容(请注意,这只是一个警告)。 因此,为避免出现此警告,您可以向您的匿名内部类添加一个serialVersionUID :
  • Enum.valueOf(String)方法从何而来?(Where does the Enum.valueOf(String) method come from?)
    问题 在Java SE 7中(并且很可能在以前的版本中),Enum类的声明如下: public abstract class Enum<E extends Enum<E>> extends Object implements Comparable<E>, Serializable Enum类具有带有此签名的静态方法: T static<T extends Enum<T>> valueOf(Class<T> enumType, String name) 但是没有静态方法:在Enum类中定义的valueOf(String)也不在Enum所属的层次结构中。 问题是valueOf(String)来自哪里? 它是语言的功能,即编译器中内置的功能吗? 回答1 该方法由编译器隐式定义。 从文档中: 请注意,对于特定的枚举类型T,可以使用对该枚举上隐式声明的公共静态T valueOf(String)方法来代替此方法,以从名称映射到相应的枚举常量。 可以通过调用该类型的隐式公共静态T [] values()方法来获取枚举类型的所有常量。 根据Java语言规范的第8.9.2节: 此外,如果E是枚举类型的名称,则该类型具有以下隐式声明的静态方法: /** * Returns an array containing the constants of this enum * type, in the
  • Java generics issue: Class “not within bounds of type-variable” error.
    I'm working on a project for class that involves generics. public interface Keyable <T> {public String getKey();} public interface DataElement extends Comparable<Keyable<DataElement>>, Keyable<DataElement>, Serializable {...} public class Course implements DataElement {...} public interface SearchTree<K extends Comparable<Keyable<K>> & Keyable<K>> extends Serializable {...} public class MySearchTree implements SearchTree<Course> { ... private class Node { public Course data; public Node left; public Node right; ... } } When trying to use the Course class within the declaration of MySearchTree
  • 如何在JSF 2.0 / 2.1中用CDI替换@ManagedBean / @ViewScope(How to replace @ManagedBean / @ViewScope by CDI in JSF 2.0/2.1)
    问题 我目前正在使用RichFaces评估Java EE 6 / JSF 2.1。 声明为的bean @ManagedBean @ViewScoped 获取一个ID集(以准备例如删除操作)。 通过JSF,将显示一个确认弹出窗口。 如果用户确认,则调用delete方法并删除在步骤1中为其存储ID的行。 由于CDI bean没有ViewScope,因此我尝试将bean声明为: @Named @ConversationScoped 现在,处理在步骤3中失败。因为在步骤1中设置的值(已检查)不再可用。 我必须使用Conversation.begin()和Conversation.end()方法吗? 如果是这样,在哪里可以调用它们? 回答1 如果可以升级到JSF 2.2,请立即执行。 它为CDI提供了本机@ViewScoped批注。 import javax.faces.view.ViewScoped; import javax.inject.Named; @Named @ViewScoped public class Bean implements Serializable { // ... } 或者,安装OmniFaces,它带来自己的与CDI兼容的@ViewScoped,包括有效的@PreDestroy (在JSF @ViewScoped上已损坏)。 import javax
  • 注解与反射(一)
    1、注解的定义与场景 1、定义 注解本身没有任何意义,单独的注解就是一种注释,他需要结合其他,如:反射、插装等技术才有意义。 Java注解(Annotation)又称Java标注,是JDK1.5引入的一种注释机制。是元数据的一种形式,提供了关于程序但不属于程序本身的数据。注解对它们注解的代码的操作没有直接影响。 我们通过@interface 来实现一个自定义注解 @Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface Lich { int value(); String id(); } 我们定义这个注解有两个元素,id 跟value,我们可以给她增加一个默认值 在后边增加一个。 @Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface Lich { int value() default 1; String id() default "努力学习"; } 2、元注解 在定义注解时,注解类也能够使用其他注解声明。对注解类型进行注解的注解类,我们称之为meta-annotation(元注解)。声明的注解允许作用于哪些节点使用@Target声明;保留级别由@Retention声明
  • Java lambda expressions, casting, and Comparators
    I was looking through Java source code for the Map interface and ran into this little snippet of code: /** * Returns a comparator that compares {@link Map.Entry} in natural order on value. * * <p>The returned comparator is serializable and throws {@link * NullPointerException} when comparing an entry with null values. * * @param <K> the type of the map keys * @param <V> the {@link Comparable} type of the map values * @return a comparator that compares {@link Map.Entry} in natural order on value. * @see Comparable * @since 1.8 */ public static <K, V extends Comparable<? super V>> Comparator<Map