我如何使这个Java 7兼容?

我有一个基本上看起来像这样的界面:
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: Method getValueName in class
net/uniqraft/murder/match/settings/ISetting has illegal modifiers: 0x1

我尝试Google,但找不到任何我理解或似乎适用于我的情况.

所以,我想,我只是将整个代码库变成Java 7:

<configuration>
    <source>1.7</source>
    <target>1.7</target>
</configuration>

我看到的第一个错误是:

Default methods are allowed only at source level 1.8 or above

这是令人难以置信的烦人,我不知道如何绕过它.我的很多代码依赖于认的实现.我想我只需要使用抽象类呢?

但是,我看到的更多的问题是在列表<设置<?>>我有

Type mismatch: cannot convert from List<ISetting<? extends Object&Comparable<?>&Serializable>> to List<ISetting<?>>

我不知道这意味着什么或如何解决它. quickfix Eclipse提供没有任何帮助.

如果您需要查看完全不被删除的ISetting类或完整的堆栈跟踪,那么我将它们放在外部,因为它们相当空间:

> ISetting.java
> Stacktrace

解决方法

我会将答案分为两部分,第一部分是关于类型推理的,第二部分涉及方法

类型推断

在Java 7中,表达式的类型与上下文无关.所以当你做:

Arrays.asList(new ClassMode(),...);

它不会创建List< ISetting<?>>.您可以通过将设置类型更改为列表<?扩展ISetting<?>&gt ;.也就是说,可以容纳可以是ISetting<?>的元素的列表.或其任何子类型:

List<? extends ISetting<?>> settings = Arrays.asList(new ClassMode(),...);

在Java 8中,将得到的列表分配给List< ISetting<?>>工作原因是poly expressions.这意味着某些表达式的推导类型可能受到目标类型的影响.所以当你做:

private List<ISetting<?>> settings = Arrays.asList(new ClassMode(),...);

编译器分析目标类型,并将类型参数隐含地传递给Arrays.asList(),这相当于执行:

private List<ISetting<?>> settings = Arrays.<ISetting<?>>asList(new ClassMode(),...);

其创建列表< ISetting<?>>并将其分配给设置.如果您不想更改设置类型,上述表单也适用于Java 7.

方法

Java 7没有方法.相反,您可以创建一个抽象的骨架实现与您的界面一起.接口将定义类型,骨架实现将提供功能.

首先,将界面中的方法转换为常规方法声明:

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
}

相关文章

最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤...
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不...
/*list 基本操作 * * List a=new List(); * 增 * a.add(inde...
/* * 内部类 * */ 1 class OutClass{ 2 //定义外部类的成员变...
集合的操作Iterator、Collection、Set和HashSet关系Iterator...
接口中常量的修饰关键字:public,static,final(常量)函数...