【问题标题】:Why ArrayList.removeRange() is not visible in the RoleList Class that extends ArrayList?为什么 ArrayList.removeRange() 在扩展 ArrayList 的 RoleList 类中不可见?
【发布时间】:2025-11-23 15:55:01
【问题描述】:

方法:ArrayList 类中的 protected void removeRange(int fromIndex,int toIndex)protected,所以我不能在 ArrayList 对象上调用它,但我可以在扩展 ArrayList 的类的对象上调用它,如下面的代码所示。但是,我们在 Java API 中有扩展 ArrayList 的类,例如:javax.management.relation Class RoleList 为什么我不能像在我的类中那样对 RoleList 类型的对象调用 removeRange():ExtendsArrayList?

public class ExtendsArrayList extends ArrayList<Integer> {
    
    public static void main (String[] args) {
        
        ExtendsArrayList list = new ExtendsArrayList();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        
        // I can call removeRange() here.
        list.removeRange(1, 3); 
        
        RoleList rl = new RoleList();
        rl.add(1);
        rl.add(2);
        rl.add(3);
        rl.add(4);
        rl.add(5);
        
        // The method removeRange(int, int) from the type ArrayList<Object> is not visible
        // Why its not visible in a class that extends ArrayList?
        //rl.removeRange(1, 3);
    }
}

编辑: 为什么我应该扩展 RoleList 以使其正常工作? RoleList extends ArrayList 芳香地,为什么我不能指望在 RoleList 的对象上调用 removeRange() 才能正常工作?换句话说,为什么ArrayList.removeRange()RoleList 类型的对象不可见,而RoleList extends ArrayList 却对我的类的对象可见:ExtendsArrayList extends ArrayListExtendsArrayList 由我扩展,RoleList 在 Java API 中扩展。

public class ExtendsRoleList extends RoleList {
    
    public static void main (String[] args) {
        
        RoleList rl = new RoleList();
        rl.add(1);
        rl.add(2);
        rl.add(3);
        rl.add(4);
        rl.add(5);
        
        // The method removeRange(int, int) from the type ArrayList<Object> is not visible
        // Why its not visible in when RoleList that extends ArrayList?
        //rl.removeRange(1, 3);
        
        ExtendsRoleList erl = new ExtendsRoleList();
        
        erl.add(1);
        erl.add(2);
        erl.add(3);
        erl.add(4);
        erl.add(5);
        
        // Why I should extend RoleList for this to work? Why its not visible when RoleList extends ArrayList automatically? 
        erl.removeRange(1, 3);
    }
}

【问题讨论】:

  • 你看到编译时问题了吗?
  • 是的,这是编译错误:“ArrayList 类型的方法 removeRange(int, int) 不可见”。
  • 就我而言,在 JDK 11 上,即使在我自己的扩展 ArrayList 的类上,我也无法调用 removeRange,就像您对 ExtendsArrayList 所做的那样。
  • 我在 Java 8 上,但我在 Java 11 API 中看到了方法:protected void removeRange​(int fromIndex, int toIndex),所以我不确定你为什么会看到编译错误。什么错误?
  • @blueSky removeRange has protected access(基本上和你的一样)。您在答案中粘贴的内容实际上是您的所有代码,还是您省略了某些内容以使其更容易?

标签: java arraylist extends protected


【解决方案1】:

protected 表示可以从子类在自身的上下文中调用protected 不代表class B1 extends A 可以在class B2 extends A 上调用A 的protected 方法。

例子:

class A {
    protected void protectedMethod() {
        //do something
    }
}

class B1 extends A { //<-- we are extending A
    public void someMethod() {
        B1 b1 = new B1();
        b1.protectedMethod(); //<-- you can call it because B1 extends A and you're in the context of B1
    }
}

class B2 { //<-- we are not extending A
    public void someMethod() { //<-- this method is exactly the same than above
        B1 b1 = new B1(); //<-- B1 is still extending A
        b1.protectedMethod(); //<-- though, you can't call the protected method anymore because you're not in the context of itself
    }
}

【讨论】:

  • 您能解释一下您的意思吗?如果类 B1 扩展了 A,即使它在不同的包中,它也可以调用 A 中的受保护方法。此外,如果类 B2 扩展 A,它可以调用 A 中的受保护方法。不一定从 B2 中的 B1 调用方法,反之亦然。请给个代码示例好吗?
  • @blueSky 问题是你没有打电话给removeRange(1,2),但你打电话给rl.removeRange(1,2)。您不是在扩展ArrayList 的类的源代码中调用方法removeRange(1,2),而是从该类的实例调用它,就好像它是一个公共方法一样。事实上,我不明白你怎么可能在你的例子中调用 list.removeRange(1,2) 而编译器不会因为同样的原因而抱怨。
  • @MatteoNNZ 这是因为他仍然在ExtendsArrayList 内部打电话。
  • @Matteo NNZ:您可以复制/粘贴我的代码,它应该可以工作。我需要证明我可以在扩展 ArrayList (ExtendsArrayList) 的类上调用 removeRange(),但在 RoleList 类扩展 ArrayList 时无法在 RoleList 对象上调用它。
  • @blueSky 我表达得不好。目前,您的代码 main 在类 ExtendsArrayList 内。保留您的课程ExtendsArrayList,但将您的main 代码移动到另一个课程中。你会看到当前正在编译的行list.removeRange(1,2),突然不能编译了,所以你应该明白chrylis想要解释什么了。
【解决方案2】:
rl.removeRange(1, 3);

您试图从无法访问的外部包(外部 lang 包)访问受保护的方法 removeRange()。所以编译器在抱怨它。

list.removeRange(1, 3); 

由于继承,您的类扩展了ArrayList,因此可以通过受保护的类修饰符直接覆盖或使用受保护的方法。

您正在调用 您的对象的方法,该方法是通过父类继承得到的,现在可以被调用,因为它成为您自定义子类的一部分。

【讨论】:

    最近更新 更多