这件事困扰了我一段时间。我问过questions之前,但可能措辞不好,例子太抽象了。所以不清楚我到底在问什么。我会再尝试。请不要仓促下结论。我预计这个问题根本不容易回答!
为什么我不能在 Java 中使用带有泛型类型参数的枚举?
问题不在于为什么它在句法上是不可能的。我知道它只是不受支持。问题是:为什么 JSR 人员“忘记”或“忽略”了这个非常有用的特性?我无法想象与编译器相关的原因,为什么它不可行。
这是我想做的事情。这在 Java 中是可能的。这是创建类型安全枚举的 Java 1.4 方法:
// A model class for SQL data types and their mapping to Java types
public class DataType<T> implements Serializable, Comparable<DataType<T>> {
private final String name;
private final Class<T> type;
public static final DataType<Integer> INT = new DataType<Integer>("int", Integer.class);
public static final DataType<Integer> INT4 = new DataType<Integer>("int4", Integer.class);
public static final DataType<Integer> INTEGER = new DataType<Integer>("integer", Integer.class);
public static final DataType<Long> BIGINT = new DataType<Long> ("bigint", Long.class);
private DataType(String name, Class<T> type) {
this.name = name;
this.type = type;
}
// Returns T. I find this often very useful!
public T parse(String string) throws Exception {
// [...]
}
// Check this out. Advanced generics:
public T[] parseArray(String string) throws Exception {
// [...]
}
// Even more advanced:
public DataType<T[]> getArrayType() {
// [...]
}
// [ ... more methods ... ]
}
然后,您可以使用 <T>在许多其他地方
public class Utility {
// Generic methods...
public static <T> T doStuff(DataType<T> type) {
// [...]
}
}
但是枚举无法做到这些:
// This can't be done
public enum DataType<T> {
// Neither can this...
INT<Integer>("int", Integer.class),
INT4<Integer>("int4", Integer.class),
// [...]
}
现在,正如我所说。我知道这些东西就是这样设计的。 enum是语法糖。泛型也是如此。实际上,编译器完成了所有工作并转换了enums。进入 java.lang.Enum 的子类和泛型转化为强制转换和合成方法。
但为什么编译器不能更进一步并允许通用枚举?
编辑: 这是我所期望的编译器生成的 Java 代码:
public class DataType<T> extends Enum<DataType<?>> {
// [...]
}
最佳答案
我要猜测一下,说这是因为 Enum 类本身的类型参数的协方差问题,它被定义为 Enum<E extends Enum<E>> ,尽管调查其中的所有极端情况有点过分。
除此之外,枚举的一个主要用例是 EnumSet 和 valueOf 之类的东西,你有一组具有不同通用参数的东西,并从字符串中获取值,所有这些都不支持或更糟的通用参数枚举本身。
我知道,当我试图对泛型产生幻想时,我总是处于痛苦的世界中,我想象语言设计者窥视了那个深渊并决定不去那里,特别是因为这些特性是同时开发的,这对于事物的枚举方面将意味着更多的不确定性。
或者换句话说,它会遇到 Class<T> 的所有问题在处理本身具有通用参数的类时,您将不得不进行大量转换和处理原始类型。语言设计者认为对于您正在查看的用例类型来说,这并不是真正值得的东西。
编辑:为了回应评论(和 Tom - 否决票?),嵌套的泛型参数会导致各种不好的事情发生。枚举实现了 Comparable。如果使用泛型,那么在客户端代码中比较枚举的两个任意元素根本行不通。一旦你处理了一个泛型参数的泛型参数,你最终会遇到各种边界问题和令人头疼的问题。很难设计一个能很好地处理它的类。在 comparable 的情况下,我想不出一种方法来比较枚举的两个任意成员,而不会恢复为原始类型并收到编译器警告。可以吗?
实际上,上面的错误令人尴尬,因为我在问题中使用数据类型作为我思考这个问题的模板,但实际上 Enum 会有一个子类,所以这不太正确。
但是,我坚持我回答的要点。汤姆长大了EnumSet.complementOf当然我们还有valueOf这会产生问题,并且就 Enum 的设计可能起作用的程度而言,我们必须意识到这是事后诸葛亮的事情。枚举是与泛型同时设计的,并没有验证所有这些极端情况的好处。特别是考虑到具有泛型参数的 Enum 的用例相当有限。 (但话又说回来,EnumSet 的用例也是如此)。
关于Java 枚举和泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5108733/
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/
HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候
遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg
我基本上来自Java背景并且努力理解Ruby中的模运算。(5%3)(-5%3)(5%-3)(-5%-3)Java中的上述操作产生,2个-22个-2但在Ruby中,相同的表达式会产生21个-1-2.Ruby在逻辑上有多擅长这个?模块操作在Ruby中是如何实现的?如果将同一个操作定义为一个web服务,两个服务如何匹配逻辑。 最佳答案 在Java中,模运算的结果与被除数的符号相同。在Ruby中,它与除数的符号相同。remainder()在Ruby中与被除数的符号相同。您可能还想引用modulooperation.
Java的Collections.unmodifiableList和Collections.unmodifiableMap在Ruby标准API中是否有等价物? 最佳答案 使用freeze应用程序接口(interface):Preventsfurthermodificationstoobj.ARuntimeErrorwillberaisedifmodificationisattempted.Thereisnowaytounfreezeafrozenobject.SeealsoObject#frozen?.Thismethodretur
在Java中,可以像这样从一个字符串创建一个IO流:Readerr=newStringReader("mytext");我希望能够在Ruby中做同样的事情,这样我就可以获取一个字符串并将其视为一个IO流。 最佳答案 r=StringIO.new("mytext")和here'sthedocumentation. 关于java-Java的StringReader的Ruby等价物是什么?,我们在StackOverflow上找到一个类似的问题: https://st