You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java不使用static时如何跨类调用protected ArrayList供类内所有方法使用

结论

可以,不需要static修饰也能实现跨类共用同一个protected修饰的ArrayList实例,核心是先满足protected的访问规则,再保证所有方法引用到的是同一个ArrayList实例即可。

核心规则说明
  • protected访问权限边界:protected修饰的非static成员,仅允许三类场景访问:
    • 同一个包下的所有类,可直接通过实例访问
    • 不同包下的子类,可访问自身继承到的该成员,或通过自身子类类型的实例访问
    • 成员所在类本身可直接访问
  • 非static成员归属逻辑:非static成员属于对象实例,不属于类,要跨类、跨方法共用同一个非static成员,本质是所有使用位置都拿到同一个对象实例持有的成员引用即可,和是否加static没有必然关系。
对应场景的实现方案

场景1:两个类在同一个包下

这是最简单的场景,直接在使用类(注:Java类名规范建议首字母大写,原示例中another建议改为Another)中持有同一个ArrayListClass实例作为成员变量,所有方法都通过这个实例访问someClass即可,示例代码:

// 和ArrayListClass定义在同一个包下
public class Another {
    // 持有唯一的ArrayListClass实例,所有方法共用这一个
    private final ArrayListClass listHolder = new ArrayListClass();

    private void method1() {
        // 直接访问同一个list
        listHolder.someClass.add(new SomeClass());
    }
    private void method2() {
        // 和method1操作的是同一个list实例
        listHolder.someClass.remove(0);
    } 
    public void method3() {
        System.out.println("当前list长度:" + listHolder.someClass.size());
    }
}

也可以直接把list引用存为Another的成员变量,不用每次链式调用,写法更简洁:

public class Another {
    private final ArrayList<SomeClass> sharedList;
    public Another() {
        // 构造时只拿一次引用,后续所有方法共用
        this.sharedList = new ArrayListClass().someClass;
    }
    // 三个方法里直接操作sharedList即可
}

场景2:两个类在不同包下

这时候有两种可选实现方式:

方式1:让Another成为ArrayListClass的子类

不同包下只有子类能访问protected成员,继承后父类的someClass会作为子类实例的成员存在,只要用的是同一个Another实例,所有方法访问的就是同一个list:

// 注意导入ArrayListClass的包路径
import com.yourpackage.ArrayListClass;

public class Another extends ArrayListClass {
    private void method1() {
        // 直接访问继承到的someClass,属于当前实例
        someClass.add(new SomeClass());
    }
    private void method2() {
        someClass.clear();
    } 
    public void method3() {
        for (SomeClass sc : someClass) {
            // 遍历逻辑
        }
    }
}

注意:这种方式下如果new多个Another实例,每个实例的someClass是独立的,要共用同一个list必须保证所有操作都基于同一个Another实例。

方式2:不继承,通过ArrayListClass提供的公开方法获取list引用

如果不想用继承,可以在ArrayListClass里加一个public的getter方法暴露list实例,这样不管是不是同包、是不是子类,只要拿到同一个ArrayListClass实例就能拿到对应的同一个list:
首先修改ArrayListClass:

public class ArrayListClass {
    protected ArrayList<SomeClass> someClass = new ArrayList<>();
    // 新增公开方法返回同一个list引用
    public ArrayList<SomeClass> getSharedList() {
        return someClass;
    }
}

然后Another类通过构造方法传入同一个ArrayListClass实例,拿到list引用存为成员即可:

public class Another {
    private final ArrayList<SomeClass> sharedList;
    // 构造时传入持有list的ArrayListClass实例
    public Another(ArrayListClass listHolder) {
        this.sharedList = listHolder.getSharedList();
    }

    private void method1() {
        sharedList.add(new SomeClass());
    }
    private void method2() {
        sharedList.remove(0);
    } 
    public void method3() {
        System.out.println(sharedList.size());
    }
}

使用时只要保证传入所有Another实例的是同一个ArrayListClass对象,就能实现跨实例、跨方法共用同一个list:

public class Main {
    public static void main(String[] args) {
        // 全局唯一的list持有对象
        ArrayListClass sharedHolder = new ArrayListClass();
        Another a1 = new Another(sharedHolder);
        Another a2 = new Another(sharedHolder);
        // a1、a2操作的都是同一个list
    }
}
避坑提醒
  • 不要在每个方法里单独new ArrayListClass(),每次new都会生成新的对象,对应的someClass也是全新的ArrayList实例,无法共用。
  • 如果不同包下Another既不是ArrayListClass的子类,ArrayListClass也没有提供暴露list的可访问方法,是无法直接访问protected修饰的someClass的,这是Java访问权限控制的硬性规则。

内容的提问来源于stack exchange,提问作者worker2

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 09:00:56