用于类
public(访问控制-公开)
- 公开的(类/接口/变量/方法);
- 父类的public方法在子类中也必须是public的;
default(访问控制-包内可用)
所有对象不加修饰符默认是包内可见可用的;
class(声明类)
- 创建Java对象的模板,描述一类对象(的行为和状态)
extends(继承父类)
- 子类可以继承父类,拥有父类非 private 的属性、方法;(使用父类的方法用super.方法名,使用子类自己的方法用this.方法名)
- 不支持多继承,但支持多重继承;
new(实例化)
- 实例化对象,调用该类型的构造函数,在堆内为其分配相应内存地址;
- 比如 Student stu= new Student(); stu是父类的一个引用,没有实际在堆中分配空间。new Student()就是在堆中为对象stu申请空间。new也实际上是在调用了父类的构造方法。
interface(声明接口)
- 声明接口时使用
- 接口不能被实例化,但可以被类实现,它包含类要实现的方法。可以将接口看做是一种只包含了功能声明的特殊类;
- 接口没有构造方法。接口中的方法会被隐式的指定为且只能为public abstract(JDK 1.8 以后,接口里可以有静态方法和方法体了。)
- 接口没有成员变量。接口中的变量会被隐式的指定为且只能为public static final 变量;
- 接口不是被类继承了,而是要被类实现。接口支持多“继承”;
- 除了抽象类,其他类必须实现接口中的全部方法;
- 标记接口:最常用的标记接口是没有任何方法的,用户让继承该接口的接口或方法被(JAVA虚拟机)识别为某一事件的代理方案。
implements(实现接口)
- 类实现接口时使用,C implements A,B (可以同时实现多个接口,变相实现多继承)
final(最终)
- final类,不能被继承,其方法自动声明为final;
- abstract 与 final不能连用(final没有子类,abstract必有子类用于实现其抽象方法)
abstract(抽象)
- 抽象的(类)不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充; 创建抽象对象的方式是先创建子类,然后 子类的实例化对象即该抽象类的对象 。
- 继承抽象类的子类如果是非抽象的,必须实现该父抽象类的所有抽象方法;
- 抽象类可以包含非抽象方法;抽象类的构造方法不能是抽象的;
用于方法
public(访问控制-公开)
- 公开的(类/接口/变量/方法);
- 父类的public方法在子类中也必须是public的;
private(访问控制-类内可用)
- 当前类内公开,类外私有(不可见)
protected(访问控制-包内可用)
- 受保护的(变量/方法),能被同一个 包(package) 中的任何类使用;
- 不同包中的子类可以使用继承基类的protected变量/方法,但不能继承基类的实例的protected变量/方法;
default(默认)
- 任何类、属性、方法不加修饰符都默认是default的;
- default关键字一般无需写出来;
- 需要写出来的场景:
switch语句中,当case里的值与switch里的key没有匹配的时候,执行default里的方法;
定义接口时使用default来修饰具体的方法,可以使接口内包含默认的具体实现方法;
abstract(抽象)
- 抽象方法必须在抽象类下;
- 构造方法不能是抽象的;
- 抽象方法不能被final修饰符修饰,因为抽象方法必须有子类实现,而final不允许有子类,不能被子类方法覆盖;abstract 与 final不能连用1
final(最终)
- final方法,不能被子类重写(不允许有子类);
static(静态)2
- 可使用对象进行访问,(对象.方法名)也可以使用类名进行访问。(类名.方法名)非静态成员方法不能使用类名访问。
- 推荐使用类名访问静态变量,因为无需关心此时对象有没有被创建。
- 函数没有直接访问到非静态的成员时才可以使用static修饰。
- 静态函数需要通过对象访问到非静态的数据。非静态的函数可以 直接访问 静态与非静态的成员。
- 静态函数 不能出现this或者super 关键字。
native(本地)
- JAVA应用可能需要与java环境外交互、与底层操作系统交互,此时非JAVA的方法需要用native修饰
- JAVA与非JAVA交互的场景原因:JAVA外环境和底层操作系统可能是非JAVA编写的;有的操作系统特性JAVA没有封装
- 使用native方法的风险:native方法不受JRE限制,可能导致病毒入侵,且由于依赖本地方法,本地方法在dll中,故丧失了可移植性(可移植性:外部环境如本地环境变化后代码的直接可用性)
strictfp(精准)
- 即 FP-strict , strict float point (精确浮点),可以用来修饰类,接口和方法,使其更精确,不会因为 不同的硬件平台导致执行结果不一致。(保证了java的可移植性)
- 使用 strictfp 关键字声明一个方法时,该方法中所有的float和double表达式都严格遵守FP-strict的限制,符合IEEE-754规范。当对一个类或接口使用 strictfp 关键字时,该类中的所有代码,包括嵌套类型中的初始设定值和代码,都将严格地进行计算。严格约束意味着所有表达式的结果都必须是 IEEE 754 算法对操作数预期的结果,以单精度和双精度格式表示。3
synchronized(同步)
- 在并发编程中存在线程安全问题,关键字synchronized可以保证在同一时刻,只有一个线程可以执行某个方法或某个代码块,同时保证一个线程的变化可见(可见性),即可以代替volatile;
- 多个线程访问同一对象同一synchronized实例方法,只有一个线程能够抢到 锁,之后其他线程就不能访问,必须等上一个线程释放才能访问。但可以直接访问非synchronized方法;
用于变量
public(访问控制-公开)
private(访问控制-类内可用)
protected(访问控制-包内可用)
final(最终)
- final变量,不可修改
static(静态)
- 用于 成员变量是共享的的时候 使用
- 可使用对象进行访问(对象.属性名),也可以使用类名(类名.属性名)进行访问。非静态成员变量不能使用类名访问。
- 静态成员变量存储在方法区内存中,只存在一份数据。非静态成员变量存储在堆内存中,n个对象有n份数据。
- 静态的成员变量数据是随着类的加载而存在,随着类文件的消失而消失;非静态的成员变量数据是随着对象的创建而存在,随着对象被垃圾回收器回收而消失。
transient(临时)
- 用于声明一个实例变量,当对象存储时,它的值不需要维持。即用transient关键字标记的成员变量不参与序列化过程。
- 即动态的临时变量,不需要存储到数据库,读该变量时,是实时获取最新值的,而非读取被序列化存储的值。(与 serializable 相反)
volatile(易变的)
- volatile声明变量的值可能随时会别的线程修改
- 可以通过缓存一致性协议保证每个线程都能获得最新值,即满足数据的“可见性”。即强制将修改的值立即写入主存,主存中值的更新会使缓存中的值失效,确保每一次取值都从内存中调取,避免取不到变量变化了的值。
- 非volatile变量不具备这样的特性,非volatile变量的值会被缓存,线程A更新了这个值,线程B读取这个变量的值时可能读到的并不是是线程A更新后的值
- volatile不具备 原子性 ,这是volatile与java中的 synchronized 、 java.util.concurrent.locks.Lock 1最大的功能差异。