目录

修饰符

注解和接口(Annotation & Interface)

访问修饰符(Access Modifier)

万能的final(Omni-final)

互斥修饰符(Mutually Exclusive Modifiers)

修饰符的申明顺序(Declaration Order of Modifiers)


修饰符

在《Java关键字分类解析》一文里已经对Java的所有关键字进行了分类归组,并对部分关键字做了一些简单的介绍分析。不过对于修饰符这部分值得更详细的探讨,所以本文就来讲述下这些修饰符在Java中的功能及应用。

Java的关键字里总共有11种修饰符,但实际上还有一种访问修饰符(Access Modifier),那就是“没有修饰”的修饰符,也就是不加任何修饰符在作用对象上。这种修饰符没有固定名称,以下都是出现过的的名字:“默认(default)”、“无修饰(No Modifier)”、“包私有(Package-Private)”、“包可见(Package)”。本文将以(package)来表示该隐形的修饰符,然后针对一共12种修饰符来作阐述。

对于所有Java的概念,可以应用修饰符的对象有三种:类(Class)、方法(Method)、变量(Variable)。进一步考虑,Java可以在类的定义里定义另一个类,所以对于类定义的位置又分出:顶层类(Top-level Class),即直接定义在文件包下的类;和嵌套类(Nested Class)。对于变量,根据其是定义在类中还是方法中,可分别定义为:类字段(Class Field)和局部变量(Local Variable)。

再进一步分类的话,嵌套类还可以分成静态嵌套类(Static Nested Class)和内部类(Inner Class),不过这只是static修饰符起的效果,所以不进一步区分。同样的对于方法也不区分静态方法和对象方法,对字段也不分静态字段(Static Field)和实例变量(Instance Variable)。对于局部变量,其实还可以细分出方法参数(Method Parameter),但它的效果基本跟方法内直接定义的变量效果一致,所以不做区分。这里也不对接口(interface)进行讨论,因为它基本相当于是完全抽象类(abstract class)

这样就得到了5种基本的修饰符作用对象,但不是所有的修饰符都可以作用在每一种对象上,所以把12种修饰符在Java中实际可作用的对象总结成下表:

MODIFIER CLASS METHOD VARIABLE
TOP-LEVEL CLASS NESTED CLASS CLASS FIELD LOCAL VARIABLE
private NO YES YES YES NO
protected NO YES YES YES NO
public YES YES YES YES NO
(package) YES YES YES YES
abstract YES YES YES NO NO
final YES YES YES YES YES
native NO NO YES NO NO
static NO YES YES YES NO
strictfp YES YES YES NO NO
synchronized NO NO YES NO NO
transient NO NO NO YES NO
volatile NO NO NO YES NO

注解和接口(Annotation & Interface)

在Java Syntax表中可以找到12种不同的修饰符,不包括(package),但包含了注解(Annotation)。由于注解可以进行自定义,也不同于本文主要讨论的修饰符针对一个作用对象只能出现一次(或没有),注解可以有多个同时作用在同一个对象上,所以不对注解做详细介绍。

另一方面,Java也有一个系统类叫Modifier,它内部定义了12种静态常量,其中11中对应着11种关键字指定的修饰符,另外一种也不是(package),而是interface。

这些静态常量其实只是比特位标记,Java库的ClassMethodField都有getModifiers()方法返回指定对象所拥有的修饰符。Modifier类里还有许多静态方法来辅助检测指定的修饰符是否存在。虽然没有任何判定(package)修饰符的方法,但其实检测对象没有publicprotectedprivate任一种修饰符,那就说明它是(package)修饰符了。

自Java 7开始,Modifier还提供方法返回可应用于各对象的修饰符的汇总,对于这些源码提供的信息也侧面反应出了表的内容:

对于interface是修饰符,想必主要是为了区别类和接口。其实Modifier还有很多非公开的常量定义,这些都不在本文讨论范围。本文的也不将interface认定为修饰符,所以研究对象还是基于表中罗列的12种修饰符。

访问修饰符(Access Modifier)

对于访问修饰符,Java开发者都不会陌生,它们的作用主要是限制类自身和其成员的可访问域。下表就是对于访问限制的总结:

MODIFIER CLASS PACKAGE SUBCLASS WORLD
public YES YES YES YES
protected YES YES YES NO
(package) YES YES NO NO
private YES NO NO NO

(想起大学刚学Java的时候,我还是将这些修饰符跟现实生活来对照进行记忆,而现在对它们的理解则已经成了条件反射式。)

回看之前的表格可以看到对于顶层类(Top-level Class),只有public(package),所以这里也提一条对于类定义的限制:
一个文件只能有一个(可以没有)公开顶层类,且该类必须和文件同名。

万能的final(Omni-final)

几乎所有修饰符都有不能应用的对象,唯独final是可以作用在所有对象上都可以修饰,但是它们的意义不完全相同。

  • 类(class): 用final修饰的类不能定义子类。
  • 方法(Method): 用final修饰的方法不能被子类覆盖。
  • 变量(Variable): 用final修饰的变量只能被初始化一次,之后变量不能再被赋值。

互斥修饰符(Mutually Exclusive Modifiers)

对一个指定的作用对象而言,可以拥有多个不同的修饰符,但不是所有修饰符都可以同时修饰一个对象的,很多修饰符之间都有互斥性。比如4种访问修饰符之间就是互斥的,只能限定一个且只有一个访问修饰符。但访问修饰符和基础修饰符之间没有任何互斥关系。

abstract几乎和其他所有基础修饰符都有互斥关系,毕竟abstract表示所修饰对象表示其内容将由子类决定,自身没有具体实现。唯一的例外就是在修饰类的时候,abstract可以和strictfp组合使用。这也可以理解,因为抽象类可以有部分方法是被实现的。

volatile修饰符只能作用在类字段上,它基本用在多线程编程方面,用以表明线程要访问字段的值时必须获取其最新的内容。它和final不能同时修饰一个字段,因为final表示字段在初始化话只能读不能写,也就不用担心它有新的值。

修饰符的互斥约束基本就这些,其实也不用去记忆它们,现代的Java编译器都能在编译时就告诉开发者哪些是不合法的修饰符组合,IDE也会对这些违规写法抛出错误来提醒开发者。

修饰符的申明顺序(Declaration Order of Modifiers)

当某个对象的修饰符满足了上述的所有条件,那这些修饰符就可以合法存在并对这个对象起作用。不过之于多个修饰在申明顺序,Java编译器并没用做强制的规定。

比如想要定义一个公开的不加入到序列化的静态常量,下边在制定类中的定义方式都是有效的(即使说statictransient放在一起一般没什么意义):

public static final transient int zero = 0;
static transient public final int one = 1;
final public transient static int two = 2;
transient final static public  int three = 3;

但为了保持编写风格的一致性,以及代码的可读性,对于修饰符的申明顺序还是有要求的。其实前面Modifier提供的修饰符汇总方法就可以反映出修饰符的申明顺序。另外,在Java Language Specification的Classes一章里也对类修饰符、方法修饰符、字段修饰符的罗列顺序也就是通常申明时要遵循的顺序。归总如下(这里将注解也包括进来)就是

  • Annotation
  • public
  • protected
  • private
  • static
  • abstract
  • final
  • native
  • synchronized
  • transient
  • volatile
  • strictfp

这个顺序也不用记忆,虽然编译器不会对它们进行约束,但有很多Checkstyle工具都会帮助开发者设定代码风格限定条件,并对不符合条件的写法抛出错误指示。


原文链接:

Java修饰符及其作用对象

一文汇总Java 修饰符相关推荐

  1. JAVA修饰符类型(public,protected,private,friendly)

    JAVA修饰符类型(public,protected,private,friendly) public的类.类属变量及方法,包内及包外的不论什么类均能够訪问: protected的类.类属变量及方法, ...

  2. java修饰符重新学习日记一

    为什么80%的码农都做不了架构师?>>> 一.java类修饰符: 1.缺省的java修饰符(默认不写情况下)修饰符为default,只能在本包中及子包下的default修饰的类中im ...

  3. Java 修饰符详解:吐血整理,带你从底层语法和开发案例疏通这 11 种常见修饰符

    文章目录 前言 一.11 种常见的 Java 修饰符 1.1.修饰符应用表 1.2.修饰符访问权限对比 二.public 修饰符 2.1.public 修饰符语法说明 2.2.public 修饰符开发 ...

  4. 03 Java 修饰符

    Java 修饰符主要分为两类: 访问修饰符 非访问修饰符 访问修饰符 public,对所有类可见 protected,对同一包内的类和子类可见 default,同一个包内的类可见 private,对当 ...

  5. java修饰符面试题

    编译并运行下面代码,请选择描述正确的项. public class XiuShiFu{ int i =10; private static float pi=3.0f;//(1) public sta ...

  6. 什么是java修饰符_java修饰符是什么?

    java修饰符用来定义类.方法或者变量,通常放在语句的最前端.(推荐:java视频教程) Java语言提供了很多修饰符,主要分为以下两类: 访问修饰符 非访问修饰符 Java语言定义了public.p ...

  7. Java修饰符与关键字

    Java修饰符与关键字

  8. JAVA 修饰符笔记

    前言 明明刚刚在写另外一篇博客的,然后准备资料的时候发现了一些懵逼的东西. 这个明显触及到了我的知识点盲区.主要是有一种很乱的感觉,没错是我菜,见识短浅啊. 直接上教程runoob Java 教程.本 ...

  9. Java修饰符、Java运算符、Java循环语句、Java条件语句、Java switch case

    Java 修饰符 Java语言提供了很多修饰符,主要分为以下两类: 访问修饰符 非访问修饰符 修饰符用来定义类.方法或者变量,通常放在语句的最前端.我们通过下面的例子来说明: public class ...

最新文章

  1. Nginx反向代理之proxy_pass指令
  2. ContOS 7 安装Jenkins
  3. 硬软链接的区别 节点 以及重定向和管道
  4. 【bzoj2118】 墨墨的等式
  5. input光标高度问题
  6. 分享一下“rmvb转avi“的操作技巧,3步搞定
  7. 系统集成项目管理工程师07《项目质量管理》
  8. 轻松学python(一)
  9. 走进Cocos Creator游戏开发(第一篇)
  10. 英国内政大臣:科技公司给信息加密不可接受
  11. Kooboo CMS - 之后台注册用户流程方法。
  12. MIT 6.824涉及的部分论文翻译
  13. shell脚本编写简易教程
  14. 3、计算圆形面积(蓝桥杯入门题)
  15. 从光学成像到计算光学成像
  16. 个人免签码支付易支付对接苹果V10插件
  17. 计算机基础-程序设计基础
  18. 通过逗号隔开,实现字符串和list集合互转以及 list集合去重
  19. Java使用mpxj导入.mpp格式的Project文件(甘特图)
  20. 新思路二级c语言程序,新思路等考通二级C

热门文章

  1. [ESP32]学习笔记05
  2. linux里的devm函数
  3. 【RabbitMQ】消息队列需要解决的几个问题
  4. Shell脚本之进制转换器
  5. 仿生学: 尺度和坐标轴
  6. 学习401k计划,建立自己的养老金投资组合
  7. 使用JavaScript DOM制作简单留言板
  8. Description 现举行新生歌手大赛,评分规则是这样的:一共有10个评委给每个歌手打分,分数采用 百分制,算分时去掉一个最高分,去掉一个最低分,取其余8个评委的平均分作为歌手的 得分。现有多个歌
  9. 乔布斯现身布道iPad 2 中国渠道商降价清库存
  10. SQL Server 下载安装教程