首页 / JAVA / 如何删除对Java枚举值的依赖?
如何删除对Java枚举值的依赖?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了如何删除对Java枚举值的依赖?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3875字,纯文字阅读大概需要6分钟。
内容图文
![如何删除对Java枚举值的依赖?](/upload/InfoBanner/zyjiaocheng/783/596642dc0c6642248999714b82219a11.jpg)
[记住差距:我知道最好的解决方案是完全摆脱枚举,但这不是评论中提到的今天的选项,但是它计划用于(远)未来.
我们有两个部署单元:前端和后端.前端使用枚举并在后端使用枚举作为参数调用EJB服务.但是枚举经常变化,所以我们不希望后端知道它的值.
字符串常量
一个可能的解决方案是使用String常量而不是枚举,但这会在前端引起很多小的变化.我正在寻找一个解决方案,它会在前端产生尽可能少的变化.
包装类
另一种解决方案是使用与枚举具有相同接口的包装类.枚举成为一个包装类,枚举值成为该包装器中的常量.我必须编写一些反序列化代码来确保对象标识(如枚举那样),但我不知道它是否是正确的解决方案.如果使用不同的类加载器怎么办?
包装器类将实现Java接口,它将替换后端中的枚举.但即使如此,deserialiaztion代码也会在后端执行吗?
包装类的示例:
public class Locomotion implements Serializable {
private static final long serialVersionUID = -6359307469030924650L;
public static final List<Locomotion> list = new ArrayList<Locomotion>();
public static final Locomotion CAR = createValue(4654L);
public static final Locomotion CYCLE = createValue(34235656L);
public static final Locomotion FEET = createValue(87687L);
public static final Locomotion createValue(long type) {
Locomotion enumValue = new Locomotion(type);
list.add(enumValue);
return enumValue;
}
private final long ppId;
private Locomotion(long type) {
this.ppId = type;
}
private Object readResolve() throws ObjectStreamException {
for (Locomotion enumValue : list) {
if (this.equals(enumValue)) {
return enumValue;
}
}
throw new InvalidObjectException("Unknown enum value '" + ppId + "'");
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (ppId ^ (ppId >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Locomotion)) {
return false;
}
Locomotion other = (Locomotion) obj;
if (ppId != other.ppId) {
return false;
}
return true;
}
}
你有没有同样的问题?你是怎么解决的?
解决方法:
好的,让我看看我是否理解.你之前这么说
“The frontend uses an enum and calls
an EJB service at the backend with the
enum as a parameter. But the enum
changes frequently, so we don’t want
the backend to know its values”
当你说“值”时,我假设你指的是你在枚举构造函数中传递的数值,而不是枚举常量本身.
因此,这意味着前端和后端将有两个不同版本的枚举类,但它们中的枚举常量将是相同的.
我只假设通过RMI进行通信(但这在你的帖子中并不完全清楚).
现在,枚举的序列化/反序列化与其他对象的工作方式不同.根据Java序列化规范,当序列化枚举时,只序列化其名称.当它被反序列化时,它是使用Enum.valueOf(name)方法构建的.
因此,您的原始包装器提议不起作用,因为服务器由于规定的Enums序列化将永远不会知道客户端中枚举的实际值.
最重要的是,如果您打算将枚举传递给服务器,则没有可能的方法来执行您假装执行的操作,因为如果隐含序列化,前端中的值将永远不会到达后端.
如果暗示RMI,一个好的解决方案是使用代码移动性,这样您就可以将有问题的类放在服务器和客户端都可访问的存储库中,并且当前端开发人员更改类定义时,您可以将类发布存储库和服务器可以从那里获取它.
请参阅此文章,了解使用RMI中的代码库属性进行动态代码下载
http://download.oracle.com/javase/6/docs/technotes/guides/rmi/codebase.html
另一个可能的解决方案是你可以停止使用Java Enum并使用带有最终常量的Java类,就像我们过去在枚举之前所做的那样,这样你就可以确保在发送它们时它的值被正确地序列化了到了后端.
有点像这样
public class Fruit implements Serializable{
private static final long serialVersionUID = 1L;
public final Fruit ORANGE = new Fruit("orange");
public final Fruit LEMON = new Fruit("lemon");
private String name;
private Fruit(String name){
this.name = name;
}
}
这样您就可以完全控制反序列化时发生的事情,并且您的包装模式可能会以这种方式工作.
这种类型的构造不能完全替换枚举,例如,它不能在switch语句中使用.但是,如果这是一个问题,您可以使用此对象作为发送到服务器的参数,并让服务器使用其枚举类的版本重建枚举.
因此,您的枚举可以有两个新方法,一个用于从枚举本身构建Java实例:
public static Fruit toFruit(FruitEnum enum);
public FruitEnum valueOf(Fruit fruit);
您可以使用它们来转换服务器参数的来回版本.
内容总结
以上是互联网集市为您收集整理的如何删除对Java枚举值的依赖?全部内容,希望文章能够帮你解决如何删除对Java枚举值的依赖?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。