Java的访问控制修饰符(public,protected,private)总结

本篇文章总结一下Java的访问修饰符,虽然这样的总结在网上已经有很多了,但是作为基础部分,还是要亲自总结一下,才能加深记忆。本文中测试使用的JDK版本是: 1.8.0_121-b13,JVM版本是:25.121-b13

1. 访问修饰符有哪些,可以用在什么地方

Java中的访问修饰符有四种,分别是public,protected,默认,private。主要作用是控制类之间的数据的访问权限。这些修饰符可以修饰的Java元素有下面这些:

  • 接口
  • 类中的方法
  • 接口中的方法
  • 类中的字段
  • 接口中的字段

注意,方法的形式参数和方法的局部变量是不可以使用权限修饰符修饰的。下面我们分别按照各个元素的维度看一下修饰符的权限控制效果。

2. 类访问控制

Java中的类除了在一个java文件中直接定义以外,还可以在一个类的内部定义类,这样的类叫做内部类。内部类也有以下几种:

  • 成员内部类
  • 静态内部类
  • 局部内部类
  • 匿名内部类

对于在文件中直接定义的类来讲,可以使用public或默认(不写)修饰符,不能使用private和protected,看下图:
在这里插入图片描述
这是因为私有的类没用意义,只能自己玩,不能与其他类交互,protected一般用于继承时,对字段和方法的控制,因此在外部定义的类使用protected修饰没用意义。注意一个java文件中,只能有一个public类出现,如果多于一个,剩下的类只能使用默认修饰符。如下图:
在这里插入图片描述

成员内部类和静态内部类都是在类中定义的,分别以一个实例成员静态成员的角色出现,这个我们讲到类的成员访问控制时再讲。

2.1. public修饰的类

如果一个类定义成public的,那么在

  • 类内部,
  • 同包的非继承类,
  • 同包的继承类,
  • 非同包的非继承类
  • 非同包继承类

这些场景中,能否访问到这个类呢?

  1. 类内部,这个当然是可以的,在一个类内部可以引用当前的类,例如在类中声明一个本类的引用
    在这里插入图片描述
  2. 同包的非继承类,我们现在,在同一包下,新建一个类ClassB,发现ClassB中也是可以引用的
    在这里插入图片描述

经过测试,public修饰的类在同包的继承类,非同包的非继承类,非同包继承类中都是可以访问的,这里就不在贴图了,大家可以在下面验证。

2.2. 默认修饰符修饰的类

其实,默认访问权限的类,在本类中,同一包(不管有没有继承关系)中都是可以访问的,但是在不同包中(不管有没有继承关系),是引用不了的,看下图:
在这里插入图片描述

3. 类中字段和方法的访问控制

在类ClassA中定义了具有四种访问控制权限字段和方法,以及静态字段和静态方法,代码如下:

package com.victory.test.modifier_test.pkg1;

public class ClassA {

    private int privateA=1;

    int defaultA=3;

    protected int protectedA=2;

    public int publicA =4;

    //---------------------------------------------------------------------

    private static int staticPrivateA=1;

    static int staticDefaultA=3;

    protected static int staticProtectedA =2;

    public static int staticPublicA =4;

    //---------------------------------------------------------------------

    private void privateFunction(){

    }

    void defaultFunction(){

    }

    protected void protectedFunction(){

    }

    public void publicFunction(){

    }

    //---------------------------------------------------------------------

    private static void privateStaticFunction(){

    }

    static void defaultStaticFunction(){

    }

    protected static void protectedStaticFunction(){

    }

    public static void publicStaticFunction(){

    }
}

3.1. 同一包下的访问控制

在本类中,这些字段和方法都是可以访问的,不再赘述。然后在同一包中新建一个类ClassB,并在其构造方法中调用这些方法和访问这些字段,结果如下;
在这里插入图片描述
同一包中,除了私有的字段和方法,其他的都可以访问,如果让ClassB继承ClassA,会有什么变化呢?其实没有什么变化的,可以得到如下结论:同一包下,private修饰的字段和方法,只有在本类中才可以访问,不同类(不管有没有继承关系)中不能访问,对于默认,protected,public修饰的字段和方法,本类其他类中都可以访问。

3.2. 不同包下的访问控制

下面再看在不同包下的情况,我们在pkg2包中定义一个类ClassC,还是在构造方法中调用这些方法和访问这些字段,结果如下;
在这里插入图片描述
如果让ClassC继承ClassA,结果会怎样呢?结果如下:
在这里插入图片描述

4. 接口的访问控制

接口和类的访问权限很相似,在一个文件中可以直接定义接口,且访问修饰符只能是public和默认,且一个java文件只能定义一个public修饰的接口,且默认访问权限的接口,在不同包中不能被引用,在接口内部可以定义:

  • 变量
  • 方法
  • 内部类
  • 内部接口

4.1. 接口中的变量

接口中定义的变量其实都是静态常量,且访问修饰符是public,所以在接口中定义变量需要初始化(常量需要初始化),如图:
在这里插入图片描述
为了进一步说明确实是常量,通过反射获取这个字段打印,
在这里插入图片描述

4.2. 接口中的方法

接口中的方法默认是 public abstract 修饰的,
在这里插入图片描述
JDK1.8以后,接口中支持default方法和static方法,都不是抽象方法,因此必须有方法体,且访问修饰符都是public。static方法可以通过接口名称直接调用,default方法可以被实现类重写。
在这里插入图片描述

4.3. 接口中的内部类和内部接口

接口中也可以声明内部类和内部接口,但是他们默认是public修饰的,且只能是public修饰的。
在这里插入图片描述
因此对于接口来说,有如下结论:

  • 接口中的成员都是public的
  • 当接口被默认修饰符修饰时,只有在同一包中才可以被引用,同时可以访问接口中的变量和方法,其他包不能引用
  • 当接口修饰符是public时,所有的包都可以引用,同时可以访问接口中的变量和方法。

5. 总结

归纳上面的验证,针对类中的字段和方法,各个访问权限修饰符的作用范围如下:
在这里插入图片描述
OK,有关Java权限控制就总结到这里了。如果您发现文中的纰漏,欢迎告诉我,我及时更正。

如果您觉得本文对你有帮助,欢迎一键三联支持一下。坚持记录,不断总结,我是张凯,一个善于总结的程序员,期待你的关注。

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值