父类从子类实现的接口的值更改会影响所有实例

马克斯·朗卡斯

考虑以下程序:

SomeClass.java:

package somepackage;

import java.util.List;

public class SomeClass implements SomeInterface {

    public SomeClass(boolean add){}

    public static void main(String[] args){
        SomeSubclass sub1 = new SomeSubclass(false);
        for (String s : sub1.getList())
            System.out.println("before: " + s);
        SomeSubclass sub2 = new SomeSubclass(true);
        for (String s : sub1.getList())
            System.out.println("after: " + s);
    }

    @Override
    public void addToList(String s) {
        someList.add(s);
    }

    @Override
    public List<String> getList() {
        return someList;
    }

}

SomeSubclass.java:

package somepackage;

public class SomeSubclass extends SomeClass {

    public SomeSubclass(boolean add){
        super(add);
        if (add)
            this.addToList("a");
    }

}

SomeInterface.java:

package somepackage;

import java.util.ArrayList;
import java.util.List;

public interface SomeInterface {

    List<String> someList = new ArrayList<String>();

    public void addToList(String s);

    public List<String> getList();

}

该程序在运行时输出以下内容:

after: a

由于SomeSubclass的第一个实例的列表为空,因此不会发送第一条调试消息。但是,一旦将元素添加到第二个实例的列表中,第一个实例也将添加该元素。分别在JDK 1.8和Java SE 8上编译和运行时,会发生这种情况。据我了解,这不应该发生。这是否是故意的,如果是的话,完成这项任务的正确方法是什么?

我还觉得我应该提到此简化代码的实际实现。我正在维护的API中有一个类,该类实现了一个称为Metadatable的接口,该接口存储了其实例的元数据映射。程序可以使用API​​通过一种方法来覆盖最近快照中的此类,完成此操作后,元数据将有效地变为静态。不用说,这会破坏API的整个元数据部分。

格特曼

这里的问题someList是隐式static(和final),因为它是在接口中定义的。

JLS的9.3节规定:

在接口的身体的每一个字段声明是含蓄publicstaticfinal可以为此类字段多余地指定任何或所有这些修饰符。

someList整个接口只有一个实例,因此所有实现类和子类都在同一列表上进行操作。

您可以执行以下两项操作之一:

  1. 将您的接口更改为一个abstract类,这样someList就不是隐式的static

  2. 将声明someList移到,SomeClass这样就不会隐式了static

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

强制从子类覆盖父类的所有虚函数

来自分类Dev

从子类的实例访问父类的属性

来自分类Dev

从子类更改超类实例变量

来自分类Dev

防止从子类访问实例变量,而不会影响基类

来自分类Dev

从子类函数访问父类实例变量

来自分类Dev

如何从子类方法实现父类方法

来自分类Dev

如何在C ++中从子类更改父类的变量?

来自分类Dev

从子类更改超类实例变量的值

来自分类Dev

为什么查询子类的所有实例比对“父”类的查询得到更多的结果?

来自分类Dev

从子类的ModelForm创建父类对象

来自分类Dev

查找类实现的所有接口

来自分类Dev

从子类本身获取js父类名称不是实例吗?

来自分类Dev

获取主类以及所有子类的所有实例

来自分类Dev

从父类继承而无需重新实现父类的子类的接口

来自分类Dev

无法从子类强制转换为父接口

来自分类Dev

自动让所有子类调用父类的方法

来自分类Dev

如何从子类的构造函数初始化父类的私有成员

来自分类Dev

跟踪超类中子类的所有实例

来自分类Dev

所有具有特定注解并实现特定接口的类

来自分类Dev

您可以从子类接口的接口调用父接口的默认方法吗?

来自分类Dev

检查父类是否是子类的实例

来自分类Dev

智能地实例化父类的子类

来自分类Dev

检查子类是否是父类的实例

来自分类Dev

Flask-SQLalchemy-从子类的父类获取关系参数

来自分类Dev

从子类构造函数中访问父类方法

来自分类Dev

在Python 2中从子类调用父类方法

来自分类Dev

在php中从子类到父类调用函数

来自分类Dev

在Unity中将值从子类更新为父类

来自分类Dev

在php中从子类到父类调用函数

Related 相关文章

热门标签

归档