1.用于定义访问权限修饰符的关键字:
private、 default 、protected 、public
2.用于定义类、函数、变量修饰符的关键字:
abstract、final、static、synchronied
3.用于定义类与类之间的关系的关键字:
extends、implements
4.用于定义建立实例及引用实例,判断实例的关键字:
new、this、super、instanceof
5.用于处理异常的关键字:
throw、throws、try、catch、finally
6.其他修饰符关键字:
volatile、native
常用关键字
-----访问权限修饰符-----
1.private(私有)
- 修饰:成员变量、成员方法、构造方法(注:不能修饰类)
- 访问权限:该类成员只能被同一类中的成员访问,不能被其他类访问。
2.default(默认的)——即不写任何关键字
- 修饰:类、成员变量、成员方法、构造方法
- 访问权限:该类成员只能被同一包中的类访问。
3.protected(被保护的)
- 修饰:成员变量、成员方法、构造方法(注:只能修饰内部类)
- 访问权限:同一个包内的所有类【如果不在同一包下的类要访问被protected修饰的成员,这个类必须是其子类】
4.public(公有的)
- 修饰:类、成员变量、成员方法、构造方法
- 访问权限:可以在任何一个类中,不管同不同包,可以任意调用
访问权限 | public | protected | default | private |
同一个类 | √ | √ | √ | √ |
同一个包 | √ | √ | √ | |
子类 | √ | √ | ||
不同包 | √ |
注:类、构造方法、带get和set的成员方法通常使用public修饰;成员变量通常采用private修饰。
访问类的成员:一种创建对象,通过对象的方法访问;一种直接访问类(前提:被访问类是其父类)
-----定义类、函数、变量修饰符的关键字------
5.abstract(抽象的)
- 修饰:类、方法
- 修饰方法时,该方法只有特征签名,没有具体实现,而是把具体实现留给继承该类的子类。
- 一个类只要有一个abstract方法,那么这个类就要被声明为abstract。
- 一个继承abstract类的子类,要么实现父类的所有abstract方法,要么声明为abstract类。
- abstract类不能创建它们的实例,因此需要创建该抽象类的一个子类(通常为内部匿名类)实现其中的抽象方法,从而创建实例。
【解释】
特征签名:特征签名=方法名+参数类型+参数顺序
内部匿名类:没有名字的内部类,只能被使用一次。(使用前提:必须继承一个父类或实现一个接口)
6.final
- 修饰:类、方法、变量(成员变量和局部变量)。
- final修饰的类不能被继承。
- final修饰的方法不能被重写(可重载)。
- final修饰的变量表示常量,只能被赋值一次。
【解释】
重写:(方法名称、方法参数、方法参数类型)相同。方法重写也叫方法覆盖。(注:重写是父类与子类之间多态性的表现)
重载:方法名称相同,但参数列表(参数数量或者参数类型)不同。(注:重载为同一个类中的多态性表现)
7.static(静态的)
- 修饰:类的成员(成员变量、成员方法、代码块)
- 被staic修饰的成员变量和成员方法不再属于对象,而是属于类,可以被该类的所有对象共享。
- 静态变量、静态方法、静态代码块
成员变量分为:
静态成员变量或类变量:被static修饰
非静态成员变量或实例变量:未被static修饰
【静态与非静态的区别】
(1)静态成员变量和非静态成员变量的区别
区别 | 静态成员变量 | 非静态成员变量 |
语法区别 | 有static修饰 | 无static修饰 |
数量区别 | 在内存中只有一份,被该类所有对象共享 | 每创建一个对象都会为成员变量分配内存,每个对象都有一份,互不干扰。 |
访问方式区别 | 通过对象名访问或 通过类名访问 | 只能通过对象名方法 |
生命周期区别 | 与类同步 (跟随类的加载而创建并初始化,跟随类的销毁而销毁) | 与对象同步 |
使用静态成员变量:当该成员变量的值需要在该类的所有对象之间共享时。
(2)静态方法和非静态方法的区别
区别 | 静态方法 | 非静态方法 |
访问方式区别 | 通过对象名访问或 通过类名访问 | 只能通过类名访问 |
注意 | 不能用super和this关键字 不能访问非静态成员变量和非静态成员方法
| 可以访问静态方法和静态成员变量 |
使用静态方法:当该方法内部不需要访问任何的非静态成员时;定义工具类(一般使用静态)。
(3)静态代码块和普通代码块的区别
静态代码块 | 普通代码块 | 构造代码块 | |
书写格式 | static {......} 在类中 | {......} 在方法中 | {......} 在类中 |
随类的加载而执行 | 出现即执行 | 随对象的创建而执行 |
常考点:执行顺序
先—>后:静态代码块(先父类后子类)——main方法——构造代码块——构造方法——普通代码块
有继承的情况:
【父类静态代码块—>父类静态成员变量初始化】—>【子类静态成员变量初始化—>子类静态代码块】—>【main方法】—>【父类普通成员变量初始化—>父类构造代码块—>父类构造方法】—>【子类构造代码块或子类普通成员变量(谁在前就先执行)—>子类构造方法】
注:
- 先静态后非静态,先父类后子类,先构造代码块后构造方法。
- 当存在多个静态代码块时或者存在多个构造方法时,按照其位置的先后顺序执行。
- 静态代码块和静态成员变量只会执行一次或初始化一次,构造代码块和普通成员变量每次创建对象都会执行或初始化。
8.synchronized
我们知道当存在多条线程共同操作共享数据时,会出现线程安全问题,那么该如何解决此问题呢?【线程安全】
方案:当存在多条线程共同操作共享数据时,就需要保证同一时刻有且只有一个线程在操作共享数据,其他线程必须等到该线程处理完数据后再进行,而这种方式就叫做互斥锁。也就是说当一个共享数据被当前正在访问的线程加上互斥锁后,在同一个时刻,其他线程就只有处于等待的状态,直到该线程处理完毕即可释放该锁。
而synchronized就可以保证在同一时刻,只有一个线程可以执行某个方法或者某个代码块,同时synchronized 可以保证一个 线程的变化(共享数据的变化)被其他线程所看到。
【原子性、可见性】
(1)synchronized使用方式:
修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁;(synchronized修饰实例对象中的实例方法)
public class SynchronizedDemo{
public Synchronized void methond(){
}
public static void main(String[] args){
SynchronizedDemo demo =new SynchronizedDemo();
demo.methond();//进入方法会锁demo指向对象中的锁;出方法会释放demo指向对象中的锁
}
}
修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁;
public class SynchronizedDemo{
public staic synchronized void methond(){
}
public static main void (String[] args){
methond();
//进入方法会锁SynchronizedDemo.class指向对象中的锁,出方法会释放SynchronizedDemo.class指向对象中的锁
}
}
修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码前要获得给定对象的锁;
public class SynchronizedDemo{
public void methond(){
//进入代码块会锁this指向对象中的锁;出代码块会释放this指向的对象中的锁
synchronized(this){
//或synchronized(SynchronizedDemo.class)
}
}
public static void main(String[] args){
SynchronizedDemo demo=new SynchronizedDemo();
demo.method();
}
}
(2)synchronized的可重入性
一个线程得到一个对象锁后再次请求该对象锁,是允许的,这就是synchronized的可重入性。
(3)synchronized与中断
事实上线程的中断操作对于正在等待获取的锁对象的synchronized方法或者代码块并不起作用。
(4)synchronized与等待唤醒机制
使用notify/notifyAll/wait方法,必须处于synchronized代码块或者synchronized方法中,否则就会抛出异常。因为这3中方法依赖于monitor对象,而synchronized可以获取monitor。
synchronized(obj){
obj.wait();
obj.notify();
obj.notifyAll();
}
-----定义类与类之间的关系的关键字-----
9.extends(继承)
class 子类 extends 父类 {}
(1)子类可以继承父类(非final修饰的类)的属性和方法,但是子类还可以拥有自己独有的属性和方法,子类还可以重写父类的方法。(子类--派生类,父类---基类)
(2)一个子类只能继承一个父类,不支持多重继承。(采用多层继承可间接实现一个子类继承多个父类的功能)
(3)子类拥有父类非private的属性、方法。
(4)继承关系中,要实例化子类的对象,默认情况下,子类会找到父类中的无参构造方法。(如果父类没有无参构造,子类通过super()调用指定参数的构造方法,注意super调用构造方法时,一定放在构造方法的首行。)
10.implements(实现)
implements关键字用于类实现接口。
接口的定义的仅仅是实现某一特定功能的一组方法的对外接口和规范,并没有真正地实现这个功能。这个功能真正实现是在“继承”了这个接口的各个类中实现的,由这些类来具体定义接口中所有抽象方法的方法体。
(1)了解接口
-->接口的定义:
接口中只能包含有名常量和没有实现的抽象方法,而不能有变量、初始化块、构造方法和方法的实现。
public interface 接口名[extends 父接口名列表]{
[public static final] 类型 有名常量名=常量值;
[public abstract] 返回值类型 方法名 {参数列表};
}
【解释】
extends 父接口名列表:用于指定要定义的接口继承于哪个父接口。
方法:接口中的方法只有定义而没有被实现。
-->接口的实现:
[修饰符] class 类名 [extends 父类名] [implements 接口列表]{
}
【解释】
extends 父类名:指定要定义的类继承哪个父类。
implements 接口列表:用于指定该类实现哪些接口。
注:
- 实现一个接口就是要实现该接口的所有方法。
- 接口可以同时继承多个接口,还可以通过extends将多个接口组合成一个接口。
- 多个无关的类可以实现同一个接口,一个类可以实现多个无关的接口。
---抽象类实现接口
普通类实现一个接口,必须要重写接口中所有的方法。
抽象类实现一个接口,可以完全重写接口中的方法,也可以只重写接口中的某几种方法。而此抽象类被继承时,其子类重写的方法即为抽象类未重写接口中的方法。
(2)接口/类/抽象类
-->接口与类的区别
类 | 接口 | |
继承性 | 单继承 | 多重继承 |
变量、初始化块、构造方法、实现方法 | 有 | 无 |
直接创建对象 | 能(除抽象类) | 不能 |
一个类只能继承一个类,一个接口可以继承多个接口。
-->接口与抽象类
不同点:
接口只有定义,其方法不能在接口中实现,只有实现接口的类才能实现接口中定义的方法;而抽象类(可以含有非抽象方法)可以有方法的定义和实现。
相同点:
都不能被实例化,只有实现了接口或者抽象类中的方法后,才能实例化。
------用于定义建立实例及引用实例,判断实例的关键字-----
11、new
new关键字用于创建对象。
(1)创建对象的步骤
- 对象声明。声明格式:类的名字 对象的名字
- 实例化。使用new创建对象。(分配内存并返回指向该内存的引用)
- 初始化。使用new创建对象时,调用构造方法初始化对象。
Person person =new Person();
new关键字是实例化对象,也是为新对象分配内存空间。
12、this
this表示当前对象,更准确地说,this代表了当前对象的一个引用。
使用场合:
(1)访问类的成员变量,解决与局部变量名称冲突问题。格式:this.变量名
在非static方法中,当局部变量或参数与类/父类的成员变量同名,按照变量作用域的规则,只能引用局部变量或参数,不能引用成员变量,但可通过this语句引用本类或者父类的成员变量。
(2)调用成员方法。格式:this.方法名
(3)调用构造方法。
在类的构造方法中,通过this语句调用本类的另一个构造方法。
格式:this( [实参表] ); 注:此语句必须位于第一行。
this应该在非static方法中使用。静态方法中不能使用this关键字,同理,this指代当前对象,静态方法不需要依赖对象,对象不存在时不能使用this。
13、super
super指向当前调用对象的父类。
super主要存在于子类方法中,用于指向子类对象中父类对象。
(1)访问父类的成员变量。格式:super.变量名
(2)访问父类的成员方法。格式:super.方法名
当子类定义和父类同名的成员变量/成员方法时,在子类范围内,父类的成员变量被隐藏/成员方法被覆盖,不能引用。所以子类通过super访问父类被隐藏的成员变量/被覆盖的成员方法。而不适用super表明引用的是子类中定义的成员变量/成员方法。
(3)访问父类的构造函数
在子类的构造方法中,通过super语句调用父类的构造方法。
格式: super( [实参表] ); 注:此语句必须位于第一行。
super | this | |
不同点 | 访问本类实例属性和方法 先找父类,没有再找父类 单独使用时,表示当前对象 | 由子类访问父类中实例属性和方法 直接在父类中找 在子类覆写父类方法时,访问父类同名方法 |
相同点 | 都是Java关键字,起到指代作用 在构造方法中必须出现在第一行 |
14、instanceof
instanceof是二元操作符,其作用是判断其左边对象是否为其右边类的实例,返回的是boolean类型的数据。
boolean result = obj instanceof Class
true/false 对象 类或接口
-----用于处理异常的关键字-----
【简单回顾异常】
1、异常类:系统自定义的异常类和用户自定义的异常类、受检查的异常和不受检查的异常
2、异常的抛出:系统自动抛出异常、throw语句抛出的异常
3、异常的捕获与处理:try/catch语句、多异常的捕获和处理
--->抛出异常
15、throw
抛出异常:在Java中,把产生异常对象并将其交给虚拟机的过程称为抛出异常。
throw语句抛出异常可以将异常显式引发。
throw语句抛出对象。 语句格式: throw 异常对象
16.throws
throws语句声明被抛出异常对象在方法体中不做处理,而由该方法的调用者处理。
throw | throws |
语句抛出异常 语法:throw 异常对象; | 方法抛出异常 语法:[修饰符] 返回值类型 方法名([参数列表])throws 异常类; |
表示抛出异常,由方法体内语句处理; | 表示抛出异常,由该方法的调用者来处理; |
throw不能单独使用 (throw和try-catch-finally配套使用或与throws配套使用) | throws可以单独使用 |
出现在函数体 | 出现在方法函数头 |
throw抛出异常,执行throw则一定抛出了某种异常。 | throws表示出现异常的一种可能性,并不一定抛出了某种异常。 |
两者都是消极处理异常的方式,只是抛出或者可能 |
编译时异常抛出必须对其进行处理,而运行时异常可处理也可不处理。
--->捕获与处理异常
在Java程序里,异常的捕获和处理语句是同时定义的。
17.try/catch/finally
(1)try/catch/finally用法:try语句定义执行进行错误测试的代码,如果try里面未发生异常,就会跳过catch语句。当try语句发生异常,就会执行catch语句进行捕获异常。但无论是什么情况最后都会执行finally语句。
(2)try/catch/finally的三种形式:
try{....}catch(参数){....}
try{....}finally{....}
try{....}catch(参数){....}finally{....}
try/finally语句只能出现一次,catch可以出现多次,也可以省略;
当存在多层抛异常时,抛出的异常只会被离它最近的catch捕获;
当try/catch/finally语句中,有return返回语句时,注意导致提前返回。
18.volatile
volatile关键字特性:保证变量在多线程之间的可见性,阻止指令重排。
19、native
native关键字说明其修饰的方法是一个原生态方法,方法对应的实现在用其他语言实现的文件中。Java语言本身不能对操作系统底层进行访问和操作,但是可以通过JNI接口调用其他语言来实现对底层的访问。