首先来一张图:

对于一个类而言访问控制符只有一个public和默认无修饰符。其他的几个访问修饰符对于变量和方法都可以使用。

下面介绍具体的使用。

1. 公有访问控制符(public)

Java的类是通过包的概念来组织的,包是类的一个松散的集合。处于同一个包中的类可以不需要任何说明二方便地相互访问和引用,而对于不同包中的类,则不行。

但如果一个类被声明为public时,它就具有了被其他包中的类访问的可能性,只要这些其他包中的类在程序中使用了import语句引入了public类,就可以访问和引用这个类。

每个Java程序的主类必须是public类,也是基于相同的原因。

用public修饰的类变量称为公共变量。如果公共变量属于公共类,则它能被所有的其他类所引用。public修饰符会造成安全性的数据封装性下降,所以一般减少public域的使用。

2. 私有访问控制符(private)

用private修饰的变量或方法只能被该类自身所访问和修改,而且不能被其他任何类(包括该类的子类)来获取和引用。private修饰符用来声明那些类的私有成员,它提供了最高的保护级别。

3. 保护访问控制符(protected)

用protected修饰的成员变量可以被3种类所引用:该类自身、与它在同一个包中的其他类、在其他包中该类的子类。使用protected修饰符的主要作用是允许其他包中该类的子类来访问父类的特定属性。

4. 默认访问控制符

默认访问控制权规定,该类只能被同一个包中的类访问和引用,而不可以被其他包中的类使用,这种访问特性又称为包访问性。

同样道理,类内的变量或方法如果没有访问控制符来规定,也就是具有包访问性。简单地说,定义在同一个程序中的所有类属于一个包。

5. 总结

简单总结一下,按它们访问范围由大到小排列如下:

public:任何地方均可访问

protected:同一包和子类可见

默认:同一包中可见

private:仅该类部可见

6. 问题

6.1 com.tuhooo和com.tuhooo.test这两个包有什么关系么?

目测没啥关系,因为包起到的是命名空间的作用,似乎并没有父包和子包的概念。

6.2 实际用protect这个访问控制符我用得比较少,倒是看见很多框架源码中用的是这个protected。

6.3 java中的访问控制符还是挺好理解的,那么在字节码层面是如何实现访问控制符的呢?

7. 访问控制符的底层探索

这里用一个比较简单的类Student.java作为示例,在这个类中四种访问控制符都用到了。

package com.tuhooo.demo.test;

public class Student {
private int age;
protected double salary;
public String name;
char sex;
}

通过如下两种命令,先编译然后得到底层的字节码。

javac Student.java
javap -verbose Student.class > info.log
Classfile /C:/Users/tuhooo/IdeaProjects/demo/src/com/tuhooo/demo/test/Student.class
Last modified 2018-5-16; size 302 bytes
MD5 checksum 92caa220b2c7efcdda2a68e7e53c63e7
Compiled from "Student.java"
public class com.tuhooo.demo.test.Student
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #3.#18 // java/lang/Object."<init>":()V
#2 = Class #19 // com/tuhooo/demo/test/Student
#3 = Class #20 // java/lang/Object
#4 = Utf8 age
#5 = Utf8 I
#6 = Utf8 salary
#7 = Utf8 D
#8 = Utf8 name
#9 = Utf8 Ljava/lang/String;
#10 = Utf8 sex
#11 = Utf8 C
#12 = Utf8 <init>
#13 = Utf8 ()V
#14 = Utf8 Code
#15 = Utf8 LineNumberTable
#16 = Utf8 SourceFile
#17 = Utf8 Student.java
#18 = NameAndType #12:#13 // "<init>":()V
#19 = Utf8 com/tuhooo/demo/test/Student
#20 = Utf8 java/lang/Object
{
protected double salary;
descriptor: D
flags: ACC_PROTECTED public java.lang.String name;
descriptor: Ljava/lang/String;
flags: ACC_PUBLIC char sex;
descriptor: C
flags: public com.tuhooo.demo.test.Student();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 3: 0
}
SourceFile: "Student.java"

主版本号(major)下面有两个字节代表访问标志(access_flags),这个标志用于识别一些类或接口层次的访问信息,包括:这个Class是类还是接口;是否定义为public类型;是否定义为abstract类型;如果是类的话是否声明为final等。具体的标志位以及标志位的含义如下表:

access_flags中一共有16个标志位可以使用,当前只定义了其中的8个,没有使用到的标志位要求一律为0。以当前的Student类为例,这是一个普通的类,不是接口、枚举或者注解,被public关键字修饰但并没被声明为fiana和abstract,并且用了JDK1.2之后的编译器进行编译,因此它的ACC_PUBLIC、ACC_SUPER标志应当为真,而上图中的其他8个标志为假,所以它的access_flags的值应该为:0x0001|0x0020=0x0021。

在大括号中分别描述了除了private之外的3中访问控制符对应的字段,就是flags对应的。话说为啥要用flags呢,不是一个字段只有一种访问控制符么?

这里只是趁着熟悉访问控制符偷看了一下字节码,不过感觉不深入。还是有几个问题:

1. 反射的时候为私有属性设置值的时候是怎么做到的?

2. 运行时怎么进行访问控制符的检查的呢?

java中的访问控制符的更多相关文章

  1. AJPFX关于java中可访问控制符和非访问控制符的详细总结

    1.类的修饰符分为:可访问控制符和非访问控制符两种. 可访问控制符是:公共类修饰符 public 非访问控制符有:抽象类修饰符 abstract :最终类修饰符 final 1 )公共类修饰符 pub ...

  2. 浅析Java中的访问权限控制

    浅析Java中的访问权限控制 今天我们来一起了解一下Java语言中的访问权限控制.在讨论访问权限控制之前,先来讨论一下为何需要访问权限控制.考虑两个场景: 场景1:工程师A编写了一个类ClassA,但 ...

  3. 分享知识-快乐自己:java 中的访问修饰符

    1):Java中的访问修饰符: Java面向对象的基本思想之一是封装细节并且公开接口.Java语言采用访问控制修饰符来控制类及类的方法和变量的访问权限,从而向使用者暴露接口,但隐藏实现细节. 访问控制 ...

  4. java中的访问修饰符详解

    主要讲述一下java中protected的修饰控制范围. 在叙述protected修饰符使用之前,先来说一下java,可以发现,开发java程序是一个时时刻刻都在编写类.开发类.定义类的过程.类里面可 ...

  5. (转)浅析Java中的访问权限控制

    原文地址: http://www.cnblogs.com/dolphin0520/p/3734915.html 今天我们来一起了解一下Java语言中的访问权限控制.在讨论访问权限控制之前,先来讨论一下 ...

  6. java中的访问修饰符

    Java有四种访问权限,其中三种有访问权限修饰符,分别为private,public和protected,还有一种不带任何修饰符.其中package代表缺省的访问权限,具体到代码中就是不写任何修饰符的 ...

  7. java类的访问控制符与其他几个特殊修饰符的总结

    1  访问控制符 1.1 字段或者方法的访问控制符   同一个类中 同一个包中 不同包中的子类 不同包中的非子类 private YES       默认(包可访问) YES YES     prot ...

  8. JAVA中的访问修饰符和包

    一.JAVA访问修饰符 访问修饰符,用来控制类中成员的可见性 有四个访问修饰符,分别是:default,private,public,protected 1.default(默认):默认权限,不用写的 ...

  9. java 中的访问修饰符

    一. public:所有类都可以访问 protected:所有子类和同包下的类都可以访问 缺省:同包类都可以访问 private:类本身才可以访问 注意点:protected修饰类属性时,例如 pac ...

随机推荐

  1. ant入门程序

    一. ant简单介绍 Ant是apache的一个核心项目, 它的作用是项目自己主动化构建, 由于它内置了Javac.Java.创建文件夹.拷贝文件等功能, 直接执行build.xml文件就能够编译我们 ...

  2. HDUOJ----1181 变形课

    变形课 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submi ...

  3. 用一个URL加一个JAVA壳做成一个安卓应用

    若想获得更新版本欢迎加入我们的 “本地应用开发webapp"群,一起协力开发一处编写处处运行的“本地应用”.我们将一直开源,将智慧共享,只有这样我们才能一起将应用体验做好! 特点: 1.程序 ...

  4. iOS “[App] if we're in the real pre-commit handler we can't actually add any new fences due

    最近运行APP,发现了这个问题,本着宁可错看,不可放过的原则,上stackoverFlow学习了一下: 链接:http://stackoverflow.com/questions/38458170/i ...

  5. PO_标准内部请购内部采购单抛转订单模组(流程)

    2014-06-03 Created By BaoXinjian

  6. OJ刷题---罗马数字转十进制

    题目要求: 输入代码: #include<iostream> using namespace std; int main() { int i,j,n,k; int num[7]= {1, ...

  7. Python 字典 clear()方法

    描述 Python 字典 clear() 方法用于删除字典内所有元素. 语法 clear() 方法语法: D.clear() 参数 无. 返回值 该方法没有任何返回值. 实例 以下实例展示了 clea ...

  8. macbook中gcc替换为gnu gcc

    macbook中gcc被定义为clang,而正统的gnu gcc却只能使用gcc-7(gcc 7版本),然而,如果修改/usr/bin的链接,还容易造成系统错误,因为mac的工具链和gcc(clang ...

  9. vim设置文本宽度

    'textwidth' 'tw'        number  (default 0)                        local to buffer                   ...

  10. php excel类 phpExcel使用方法介绍

    phpExcel操作excel可以方便的加入图片,支持jpg gif png格式. 下载地址:http://www.codeplex.com/PHPExcel 下面是总结的几个使用方法 include ...