加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

我如何使这个Java 7兼容?

发布时间:2020-12-14 17:41:25 所属栏目:Java 来源:网络整理
导读:我有一个基本上看起来像这样的界面: public interface ISettingT { public T getDefault(); public T value(); public void set(T value); public String getName(); public default String getValueName() { Object obj = value(); if (obj instanceof Boo
我有一个基本上看起来像这样的界面:
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
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读