1.介绍
什么是修饰符?在我的理解下修饰符相当于一种标签,可以作用于组成Java程序的三种元素(类、方法、变量)。在进行Java开发的过程中,我们可以这么使用标签:
场景1:
甲:哇,我写的这个类写的太完美了叭??看起来不需要在做什么扩展了,我的其他同事们应该也没扩展它的能力了吧?让我给他加个final标签不允许其他人继承乱改乱扩展了。(当然实际上final修饰在类上通常是表示该类有特定的作用,如String)
场景2:
乙:这个支付功能以后应该会对接不少平台的支付吧?算了 给这个支付方法贴上abstract标签吧,让其他人写子类实现去~
场景3:
丙:嗯~总算把这个支付宝支付的功能写完了,这堆和支付宝交互的方法他们也用不上,给他们留着支付方法就行,其他我就先private私有化拉。
听起来Java修饰符好像很强大的样子,那么在Java中有哪些修饰符呢?修饰符根据修饰的对象不同可分为三种:类修饰符、变量修饰符、方法修饰符。根据其用途可分为:访问修饰符和非访问修饰符。
接下来我们先大概了解一下有哪些修饰符,在进行详细说明
- 类修饰符:
- 访问修饰符:public(公共访问)、default(同包访问)
- 非访问修饰符: abstract(抽象类)、final(最终类)
- 方法修饰符:
- 访问修饰符:public(公共访问)、protected(同包、子类(主要目的是给子类访问))、default(同包访问)、private(保护型,仅本类)
- 非访问修饰符:abstract(抽象方法)、static(静态方法)、final(最终方法)、synchronized(同步方法)、native(本地方法)
- 变量修饰符:
- 访问修饰符:public(公共访问)、protected(同包、子类(主要目的是给子类访问))、default(同包访问)、private(保护型,仅本类)
- 非访问修饰符:static(静态变量)、final(常量)、volatile(易变修饰符)、transient(暂时性域修饰符)
2.详解
2.1 访问修饰符
2.1.1 Public
公共访问修饰符,可用于修饰类、方法、变量。表明没有任何访问限制。
2.1.2 Protected
保护访问修饰符,可用于修饰方法、变量。修饰后表明该方法/变量仅能被同包下的类、子类访问。该修饰符的意义一般是指开放给子类访问。
2.1.3 Default
默认访问修饰符,可用于修饰类、方法、变量。修饰后表明该元素只能被同一个包下的类访问。
注:此处的default通常是指不带任何修饰符的默认级别,后来jdk1.8新增关键字default修饰符,是用于修饰接口的默认方法。
2.1.4 Private
私有访问修饰符,可用于修饰方法、变量。修饰后表明该元素只能被自己使用。
注意:一个类的内部类可以被其他访问控制修饰符protected、default、private修饰,相当于类的成员。
2.2非访问修饰符
2.2.1 Abstract
抽象修饰符,可作用于类、方法上。
修饰在类上表明该类为抽象类,修饰在方法上表示该方法为抽象方法没有实现体。
2.2.2 Final
最终修饰符,可作用于类、方法、变量上。
修饰在类上表明为最终类(简单地说就是自宫了不能再有子类了),修饰在方法上表明是最终方法不可重写,修饰在变量上表明为常量(需要初始化,这涉及到了类加载顺序等 问题)。
2.2.3 Static
静态修饰符,可作用于方法、变量上。
当方法加上Static时,表明了该方法不再依赖对象,此时Static方法无法访问成员变量及成员方法,因为在调用的时候可能并不存在对象。通常设计在你希望外部不需要new实例即可访问的方法上。
当变量加上Static时,该变量被所有的对象所共享,在内存中只有一个副本。通常设计在你希望某个变量被所有对象所共享。
2.2.4 Native
本地方法修饰符,可作用于方法上。
native方法的实现不在Java类上,而是通过JNI去调用了其他语言实现的方法,由于Java本身无法操作许多系统底层的东西,这时候便需要native修饰符来调用其他如C/C++所实现的功能。可通过创建.h文件用其他语言实现后生成动态链接库实现。
2.2.5 Synchronized
同步方法修饰符,可作用于方法上。
synchronized可以保证方法或者代码块在运行时,同一时刻只有一个方法可以进入到临界区,同时它还可以保证共享变量的内存可见性(即代替volatile)
2.2.6 Volatile
易变修饰符,可作用于变量上。
使用该修饰符的变量,说明变量的值可能随时会别的线程修改,使用volatile修饰的变量会强制将修改的值立即写入主存,也就是使用了Volatile后会禁止掉JVM的指令重排。什么是指令重排?大致就是JVM为了性能考虑在不影响执行结果的基础上对代码顺序进行调整。当不使用Volatile关键字时可能会由于指令重排改变了代码顺序导致了在多线程环境下变量值无法按我们预期执行。
2.2.7 Transient
暂时性域修饰符,可作用于变量上。
使用该修饰符的变量,说明变量是暂时性的不需要参与对象的持久性存储,也就是当Java序列化时会忽略掉该参数的值。
小贴士
接口变量默认修饰符是:public static
接口方法默认修饰符是: public abstract
另外接口方法在jdk1.8新增default修饰符表示接口允许有默认实现的方法。
总结
修饰符是一个既基础也强大的利器,虽然看似与程序逻辑关系不大,但运用得当也能给代码的性能、安全性等带来便利(当然也有可能挖坑)。访问修饰符让我们很好的控制了外部类的访问权限,可以自由灵活的展示出想要展示的一面;非访问修饰符也是有着强大的功能,既可以保证我们不想被修改的方法/变量不被修改,也能用volatile警告jvm不许给我们挖坑。
总而言之,编程的每个知识点都有着极大的价值,路漫漫其修远兮加油。