![](/img/trans.png)
[英]How do I make sure that a java program is compatible with Java Enviornment 6?
[英]How would I make this Java 7 compatible?
我有一个基本上看起来像这样的接口:
public interface ISetting<T> {
public T getDefault();
public T value();
public void set(T value);
public String getName();
public default String getValueName() {
Object obj = value();
if (obj instanceof Boolean) {
return (boolean)obj ? "Yes" : "No";
}
return obj.toString();
}
}
然后在另一个班级中我有一个ISetting<?>
private List<ISetting<?>> settings = Arrays.asList(
new ClassMode(),
new EndMode(),
new PlayerLives(),
new JoinMidGame(),
new ScoreboardDisplay(),
new LifePerKill(),
new ExplosiveBullets(),
new ReloadTime());
这一切都完美无缺! 但是,我使用我的代码的平台不支持Java 8,所以我必须使用Java 7,这就是问题所在。
如果我将Maven目标设置为1.7,就像在我的pom.xml中一样:
<configuration>
<source>1.8</source>
<target>1.7</target>
</configuration>
然后代码完美编译,没有错误或任何东西。 但是,当我尝试运行代码时,它给了我这个错误:
java.lang.ClassFormatError:类net / uniqraft / murder / match / settings / ISetting中的方法getValueName具有非法修饰符:0x1
我尝试谷歌它但找不到我理解或似乎适用于我的情况。
所以,我想,我只是将整个代码库变成Java 7:
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
我看到的第一个错误是:
仅在源级别1.8或更高级别允许默认方法
这令人难以置信的烦恼,我不知道如何绕过它。 我的很多代码都依赖于默认实现。 我想我只需要使用抽象类代替?
但是我看到的更有问题的错误是List<Setting<?>>
我有:
Type mismatch: cannot convert from List<ISetting<? extends Object&Comparable<?>&Serializable>> to List<ISetting<?>>
我不知道这意味着什么或如何解决它。 Eclipse提供的quickfix没有任何帮助。
如果您需要查看完整的非剥离ISetting类或完整的堆栈跟踪,我将它们放在外部,因为它们相当宽敞:
我将把答案分为两部分,第一部分是关于类型推断,第二部分是关于默认方法:
类型推断
在Java 7中, 无论上下文如何,表达式的类型都是相同的 。 所以当你这样做时:
Arrays.asList(new ClassMode(), new EndMode(), ...);
它不会创建List<ISetting<?>>
。 您可以通过将settings
类型更改为List<? extends ISetting<?>>
来使其工作List<? extends ISetting<?>>
List<? extends ISetting<?>>
。 也就是说,一个列表可以包含可以是ISetting<?>
或其任何子类型的元素:
List<? extends ISetting<?>> settings = Arrays.asList(new ClassMode(), new EndMode(), ...);
在Java 8中,将结果列表分配给List<ISetting<?>>
是因为List<ISetting<?>>
表达式 。 这意味着某些表达式的推导类型可能受目标类型的影响 。 所以当你这样做时:
private List<ISetting<?>> settings = Arrays.asList(new ClassMode(), new EndMode(), ...);
编译器分析目标类型并隐式地将类型参数传递给Arrays.asList()
,这相当于:
private List<ISetting<?>> settings = Arrays.<ISetting<?>>asList(new ClassMode(), new EndMode(), ...);
这会创建一个List<ISetting<?>>
并将其分配给settings
。 如果您不想更改settings
类型,上面的表单也适用于Java 7。
默认方法
Java 7没有默认方法。 相反,您可以创建一个抽象的骨架实现来与您的界面一起使用。 接口将定义类型,骨架实现将提供默认功能。
首先,将接口中的default
方法转换为常规方法声明:
public interface ISetting<T> {
T getDefault();
T value();
void set(T value);
String getName();
// Former default methods:
String getValueName();
boolean isHidden();
boolean isDefault();
// etc.
}
然后创建一个抽象类来保存默认实现:
public abstract class AbstractSetting<T> implements ISetting<T> {
@Override
public String getValueName() {
Object obj = value();
if (obj instanceof Boolean) {
return ((Boolean) obj) ? "Yes" : "No";
}
return obj.toString();
}
@Override
public boolean isHidden() {
return false;
}
// etc.
}
现在让您的具体类实现ISetting<T>
接口并扩展AbstractSetting<T>
类。 例如:
public class ConcreteSetting extends AbstractSetting<Boolean> implements ISetting<Boolean> {
// concrete implementation
}
您需要执行以下操作之一:
getValueName()
删除默认修饰符
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.