一、总述
类、方法、成员变量和局部变量的可用修饰符
修饰符 | 类 | 成员访求 | 构造方法 | 成员变量 | 局部变量 |
---|---|---|---|---|---|
abstract(抽象的) | √ | √ | - | - | - |
static (静态的) | - | √ | - | √ | - |
public(公共的) | √ | √ | √ | √ | - |
protected(受保护的) | √ | √ | √ | - | |
private(私有的) | - | √ | √ | √ | - |
synchronized(同步的) | - | √ | - | - | - |
native(本地的) | - | √ | - | - | - |
transient(暂时的) | - | - | - | √ | - |
volatie(易失的) | - | - | - | √ | - |
final(不要改变的) | √ | √ | - | √ | √ |
二、类修饰符
访问修饰符:公共类修饰符public(只能是它)
非访问控制符:抽象类修饰符 abstract 、最终类修饰符 final
(1)公共类修饰符 public : Java 语言中类的访问控制符只有 public 即公共的。每个 Java 程序的有且只有一个类是 public,它被称为主类 ,其他外部类无访问控制修饰符,具有包访问性。注意:一个类的内部类可以被其他访问控制修饰符protected、default、 private修饰,相当于类的成员。
(2)抽象类修饰符 abstract :用 abstract 修饰符修饰的类,被称为抽象类。
(3)最终类修饰符 final :当一个类不能被继承时可用修饰符 final修饰为最终类。被定义为 final 的类通常是一些有固定作用、用来完成某种标准功能的类。final关键字不能用来抽象类和接口
(4)类缺省访问控制符:如果一个类没有访问控制符,说明它具有缺省的访问控制符特性。此时,这个类只能被同一个包中的类访问或引用。这一访问特性又称为包访问性。
1、如果一个类包含抽象方法(用abstract修饰的方法),那么这个类必须是抽象类
2、继承抽象类的子类必须重写父类所有的抽象方法(用abstract修饰的方法)。否则,该子类也必须声明为抽象类(也必须用abstract修饰)。最终,必须有子类实现该父类的抽象方法,否则,从最初的父类到最终的子类都不能创建对象,失去意义。
接口通常是不带修饰符的,一般都是public interface
以上是对于外部类,外部类只能用public、adstract、final修饰,如果是内部类类则可以用 修饰成员变量的修饰符修饰内部类,比如 private, static, protected 修饰。
三、方法修饰符
1、按修饰符分
访问控制修饰符:公共访问控制符public、保护访问控制符protected、缺省默认default、私有访问控制符private
非访问控制符:抽象方法控制符abstract 、静态方法控制符static 、最终方法控制符final 、本地方法控制符native 、同步方法控制符synchronized
(1)抽象方法控制符 abstract :用修饰符 abstract 修饰的方法称为抽象方法。抽象方法仅有方法头,没有方法体和操作实现。
(2)静态方法控制符 static :用修饰符 static 修饰的方法称为静态方法。静态方法是属于整个类的类方法;而不使用static 修饰、限定的方法是属于某个具体类对象的方法。 由于 static方法是属于整个类的,所以它不能操纵和处理属于某个对象的成员变量,而只能处理属于整个类的成员变量,即 static 方法只能处理 static的域。
(3)最终方法控制符 final :用修饰符 final修饰的方法称为最终方法。最终方法是功能和内部语句不能更改的方法,即最终方法不能重写覆盖(可以被继承)。final固定了方法所具有的功能和操作,防止当前类的子类对父类关键方法的错误定义,保证了程序的安全性和正确性。所有被 private 修饰符限定为私有的方法,以及所有包含在 final 类 ( 最终类) 中的方法,都被认为是最终方法。
(4)本地方法控制符 native :用修饰符 native 修饰的方法称为本地方法。为了提高程序的运行速度,需要用其它的高级语言书写程序的方法体,那么该方法可定义为本地方法用修饰符 native 来修饰。
(5)同步方法控制符 synchronized :该修饰符主要用于多线程程序中的协调和同步。
2、类的方法
类成员的访问控制符:即类的方法和成员变量的访问控制符
一个类作为整体对象不可见,并不代表他的所有域和方法也对程序其他部分不可见,需要有他们的访问修饰符判断。权限如下:
访问修饰符 | 同一个类 | 同包 | 不同包,子类 | 不同包,非子类 |
---|---|---|---|---|
public | √ | √ | √ | √ |
protected | √ | √ | √ | |
默认(default) | √ | √ | ||
private | √ |
(1)构造方法
构造方法只能用public(所有的类访问)、protected(只能自己和子类访问)、private(只能在本类访问),而不能是abstract, static, final, native, strictfp, 或者synchronized的。原因如下:
- 构造器不是通过继承得到的,所以没有必要把它声明为final的。
- 同理,一个抽象的构造器将永远不会被实现。(所以也不能声明为abstract的)
- 构造器总是关联一个对象而被调用,所以把它声明为static是没有意义的。
- 没有实际的需要把构造器定义成同步的,因为它将会在构造的时候锁住该对象,直到所有的构造器完成它们的工作,这个构造的过程对其它线程来说,通常是不可访问的。 (synchronized)
- 本地化的方法情况特别复杂,所以JVM调用起来非常麻烦,需要考虑很多种情况,没有native关键字的情况下,JVM实现起来比较容易。
(2)类方法(静态方法)
类方法:使用static关键字说明的方法(与实例方法区分:是否用static修饰)
1.系统只为该类创建一个版本,这个版本被该类和该类的所有实例共享。
2.类方法只能操作类变量,不能访问实例变量。类方法可以在类中被调用,不必创建实例来调用,当然也可以通过对象来调用。
3.静态方法可以直接访问类变量(静态成员变量)和静态方法。
解释:因为静态方法在加载类的时候就被调用了
4.静态方法不能直接访问普通成员变量或成员方法。反之,成员方法可以直接访问类变量(静态成员变量)或静态方法。
普通成员变量或成员方法只有在创建对象的时候才会被创建,而静态方法在加载类的时候就被加载了,那时候还没有对象,更不必谈在静态方法中访问其中的普通成员变量和成员方法了
5.静态方法中,不能使用this关键字。
(3)成员方法
- public(公共控制符)
- private(私有控制符)指定此方法只能有自己类等方法访问,其他的类不能访问(包括子类)
- protected(保护访问控制符)指定该方法可以被它的类和子类进行访问。
- final,指定该方法不能被重载。
- static,指定不需要实例化就可以激活的一个方法。
- synchronize,同步修饰符,在多个线程中,该修饰符用于在运行前,对他所属的方法加锁,以防止其他线程的访问,运行结束后解锁。
- native,本地修饰符。指定此方法的方法体是用其他语言在程序外部编写的。
(4)抽象类的抽象方法
抽象类中的抽象方法(其前有abstract修饰)不能用private、static、synchronized、native访问修饰符修饰。原因如下:
- 抽象方法没有方法体,是用来被继承的,所以不能用private修饰;
- static修饰的方法可以通过类名来访问该方法(即该方法的方法体),抽象方法用static修饰没有意义;
- 使用synchronized关键字是为该方法加一个锁。而如果该关键字修饰的方法是static方法。则使用的锁就是class变量的锁。如果是修饰类方法。则用this变量锁。但是抽象类不能实例化对象,因为该方法不是在该抽象类中实现的,是在其子类实现的。所以,锁应该归其子类所有。所以,抽象方法也就不能用synchronized关键字修饰了;
- native,这个东西本身就和abstract冲突,他们都是方法的声明,只是一个把方法实现移交给子类,另一个是移交给本地操作系统。如果同时出现,就相当于即把实现移交给子类,又把实现移交给本地操作系统,那到底谁来实现具体方法呢?
3、接口的方法
接口是一种特殊的抽象类,接口中的方法全部是抽象方法(但其前的abstract可以省略),所以抽象类中的抽象方法不能用的访问修饰符(private、static、synchronized、native)这里也不能用。而且protected访问修饰符也不能使用,因为接口可以让所有的类去实现(非继承),不只是其子类(比如如果实现类和接口不在同一个包内就会出现问题)。所以要用public去修饰,接口才可以被实现。
默认写法:public abstract(默认不写)
(1)静态方法(static)
用static修饰的方法就是静态方法,静态方法必须要有实现体(一定要有花括号),并且静态方法是不能被实现类实现的,只能通过接口调用这个方法
静态方法必须要有方法体,即一定要有花括号,是因为静态方法不能被实现类实现,但是接口的方法又必须全部被实现,所以矛盾,所以静态方法必须要有实现
格式:public static 返回数据类型 方法名(参数列表){}
省略了abstract
(2)默认方法(default)
default的加入就是为了解决接口中不能有默认方法的问题,在实现类中可以重写这个default方法也可以不重写。
default修饰的方法跟接口中的静态方法的区别就是default方法可以被实现类重写,这样就可以得到扩展并且不修改原来接口中功能,而静态方法就有点太苛刻了,还不如把静态方法写在实现类中,这样每个实现类都可以自己写自己的功能实现。
格式:default 返回数据类型 方法名(){}
(3)其他抽象方法
四、变量修饰符
1、类的成员变量修饰符
一个类的成员变量的声明必须在类体中,而不能在方法中,方法中声明的是局部变量。
public(公共访问控制符),指定该变量为公共的,他可以被任何对象的方法访问。
private(私有访问控制符)指定该变量只允许自己的类的方法访问,其他任何类(包括子类)中的方法均不能访问。
protected(保护访问控制符)指定该变量可以别被自己的类和子类访问。在子类中可以覆盖此变量。
friendly ,在同一个包中的类可以访问,其他包中的类不能访问。
final,最终修饰符,指定此变量的值不能变。
static(静态修饰符)指定变量被所有对象共享,即所有实例都可以使用该变量。变量属于这个类。
transient(过度修饰符)指定该变量是系统保留,暂无特别作用的临时性变量。
volatile(易失修饰符)指定该变量可以同时被几个线程控制和修改。
抽象类中变量的修饰符与一般类一致
2、接口中的变量
接口中的属性默认是public static final 的,(因为是final的,所以都是常量),只能读不能改
public static final 可以省略不写
即
1:public static final String name = “张三”;
2:String name = “张三”;
以上两种写法都可以
public的话可以理解,需要被实现类使用
如果是非static的话,因一个类可以多继承,容易出现重名导致编译错误
接口的方法都是抽象的,可变的东西都应该归属到实现类中,这样接口才能起到标准化、规范化的作用,因此接口里的属性必须是不变的,即final的,可以不变实现类修改(如果能被实现类任意修改,接口就没有创建这个常量的必要了
3、方法中的局部变量
因为接口中的方法都是抽象方法,而抽象方法没有实现,即没有方法体。所以,只有一般类中的方法和抽象类中的非抽象方法才会有局部变量。
方法中对于变量的修饰符只有两种:
1、缺省(default):即什么都不写,这是一个普通的变量,必须为其设置初始值。
2、final:表示变量值不可以被改变,即常量
一般类和抽象类中的静态方法中的变量自动就是静态的,不需要加static
五、常考修饰符
1、final
(1)修饰类
- 该类不能被继承
- final不能修饰抽象类和接口
- final类中的方法不会被覆盖,因此默认都是final的
- 用途:设计类时,如果该类不需要有子类,不必要被扩展,类的实现细节不允许被改变,那么就设计成final类
(2)修饰方法
- 该方法可以被继承,但是不能被覆盖
- 用途:一个类不允许子类覆盖该方法,则用final来修饰
- 好处:可以防止继承它的子类修改该方法的意义和实现;更为高效,编译器在遇到调用fianal方法转入内嵌机制,提高了执行效率
- 父类中的private成员方法不能被子类覆盖,因此,父类的private方法默认是final型的(可以查看编译后的class文件)
(3)修饰变量
- 用final修饰后变为常量。包括静态变量、实例变量和局部变量这三种
- **特点:**只能被赋一次值,必须被显示初始化。可以先声明,不给初值,这种叫做final空白。但是使用前必须被初始化。一旦被赋值,将不能再被改变。
(4)修饰参数
- 用final修饰参数时,可以读取该参数,但是不能对其作出修改
2、static
1、简介
关于 static 关键字的使用,它可以用来修饰的成员变量和成员方法,被修饰的成员是属于类的,而不是单单是属 于某个对象的。也就是说,既然属于类,就可以不靠创建对象来调用了。
2、定义和使用
1)类变量当 static 修饰成员变量时,该变量称为类变量。
该类的每个对象都共享同一个类变量的值。任何对象都可以更改该类变量的值,但也可以在不创建该类的对象的情况下对类变量进行作。
static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。 static成员变量的初始化顺序按照定义的顺序进行初始化。
定义格式:static 数据类型 变量名;举例:static int numberID;
2)静态方法
当 static 修饰成员方法时,该方法称为类方法 。
静态方法在声明中有 static ,建议使用类名来调用,而不需要创建类的对象。调用方式非常简单。 类方法:使用 static关键字修饰的成员方法,习惯称为静态方法。 定义格式: 修饰符 static 返回值类型 方法名 (参数列表){ // 执行语句}
调用格式:
被static修饰的成员可以并且建议通过类名直接访问。虽然也可以通过对象名访问静态成员,原因即多个对象均属 于一个类,共享使用同一个静态成员,但是不建议,会出现警告信息。
3)静态代码块
定义在成员位置,使用static修饰的代码块{ }。 位置:类中方法外。执行:随着类的加载而执行且执行一次,优先于main方法和构造方法的执行。
3、注意事项:
- 静态方法可以直接访问类变量和静态方法。
- 静态方法不能直接访问普通成员变量或成员方法。
- 反之,成员方法可以直接访问类变量或静态方法。
- 静态方法中,不能使用this和super关键字。
- 静态方法不能被abstract修饰
- 静态方法和静态变量都可以通过类名直接被访问。
- 当类被加载时,静态代码块只被执行一次。类中不同的静态代码块按它们在类中出现的顺序被依次执行
static 关键字,可以修饰变量、方法和代码块。在使用的过程中,其主要目的还是想在不创建对象的情况
3、注意事项:
- 静态方法可以直接访问类变量和静态方法。
- 静态方法不能直接访问普通成员变量或成员方法。
- 反之,成员方法可以直接访问类变量或静态方法。
- 静态方法中,不能使用this和super关键字。
- 静态方法不能被abstract修饰
- 静态方法和静态变量都可以通过类名直接被访问。
- 当类被加载时,静态代码块只被执行一次。类中不同的静态代码块按它们在类中出现的顺序被依次执行
static 关键字,可以修饰变量、方法和代码块。在使用的过程中,其主要目的还是想在不创建对象的情况