今天我们来浅谈一下修饰词
修饰词 | 使用对象 | 介绍 |
public | 类、接口、成员(自身类) | 无论它所在的包定义在哪,该类(接口、成员)都是可访问的 |
private | 成员(自身类) | 成员只可以在定义它的类中被访问 |
static | 类、方法、字段、初始函数 | 成名为static的内部类是一个顶级类,它和包含的成员是不相关的。静态方法是类方法,是被指向到所属的类而不是类的实例。静态字段是类字段,无论该字段所在的类创建了多少实例,该字段只存在一个实例被指向到所属的类而不是类的实例。初始化函数是在装载类时执行的,而不是在创建实例时执行的。 |
final | 类、方法、字段、变量 | 被定义成final的类不允许出现子类,不能被覆盖(不应用于动态查询),字段值不允许被修改。 |
abstract | 类、接口、方法 | 类中包括没有实现的方法,不能被实例化。如果是一个abstract方法,则方法体为空,还方法的实现在子类中被定义,并且包含一个abstract方法的类必须是一个abstract类 |
protected | 成员(自身类) | 成员只能在定义它的包中被访问,如果在其他包中被访问,则实现这个方法的类必须是改该成员所属的子类。 |
native | 成员(自身类) | 与操作平台相关,定义时并不定义其方法,方法的实现被一个外部的库实现。 |
strictfp | 类、方法 | strictfp修饰的类中所有的方法都隐藏了strictfp修饰词,方法执行的所有浮点。 |
synchronized | 方法 | 对于一个静态的方法,在执行之前jvm把它所在的类锁定;对于一个非静态的方法,执行前把某个特定对象实例锁定。 |
volatile | 字段 | 因为异步线程可以访问字段,所以有些优化操作是一点不能作用在字段上的。 |
transient | 字段 | 字段不是对象持久别的一部分,不应该把字段和对象放在一起。 |
公共类型 public;
public 可以修饰类,成员变量。构造方法被public修饰的成员,可以在任何一个类是权限最大的一个修饰符。
私有类型 private;
可以修饰成员变量,构造方法,成员方法,不能修饰类(此处指外部,不考虑内部类)。被private\修饰的成员,只能在定义它们的类中使用,在其他类中不能调用 。
默认类型:default;
可用于修饰类,成员变量,构造方法,方法,都能够使用默认权限,即不写任何的关键字。默认权限即同包权限,同包权限的元素只能定义它们的类中,以及同包的类中被调用。
保护类型protected;
可以修饰数据成员,构造方法,方法成员,不能修饰类(此处指外部类,不考虑内部类)。
被protected修饰的成员,能在定义它们的类中,同包的类中被调用。
如果有不同包的类想调用它们,那么这个类必须是定义它们的子类。
我们可以用一个表格更加直观的看到它们的区别
public | protected | defult | private | |
同类 | ✔ | ✔ | ✔ | ✔ |
同包 | ✔ | ✔ | ✔ | |
不同包子类 | ✔ | ✔ | ||
不同包的其他类 | ✔ |
关于权限修饰符还要有注意几个问题:
1.并不是每个修饰符都可以修饰类(指外部类),只有public和default可以。
2.所有修饰符都可以修饰数据成员,方法成员,构造方法。
3.为了代码安全起见,修饰符不要尽量使用权限大的,而是适用即可。比如,数据成员,如果没有特殊需要。
4.修饰符修饰的是“被访问”的权限。
public class Demo2 {
public int a;//定义一个公共类型的整型变量a
protected int b;//定义一个保护类型的整型变量b
int c;//定义一个默认类型的整型变量b=c
private int d;//定义一个私有类型的整型变量d
Demo2 demo2 = new Demo2();
//在本类中4种修饰符都可以调用
{
System.out.println(demo2.a);
System.out.println(demo2.b);
System.out.println(demo2.c);
System.out.println(demo2.d);
}
public void run()
{
System.out.println("跑步"); }
protected void run1(){
System.out.println("跑步"); }
void run2(){
System.out.println("跑步"); }
private void run3(){
System.out.println("跑步");
}
{
demo2.run();
demo2.run1();
demo2.run3();
demo2.run2();
}
}
//同包下不同类
public class Demo3 {
public static void main(String[] args) {
Demo2 demo2=new Demo2();
//私有类型不能被进行调用
System.out.println(demo2.a);
System.out.println(demo2.b);
System.out.println(demo2.c);
demo2.run1();
demo2.run2();
demo2.run();
package com.pratice.Cfx;//不同包的子类
import com.pratice.day2.Demo2;
//extends 子类继承父类,但并不是全部继承!
public class Demo1 extends Demo2 {
public static void main(String[] args) {
Demo1 demo=new Demo1();
//可以调用公共还有保护类型的变量
System.out.println(demo.a);
System.out.println(demo.b);
}
}
在修饰符中我们最常见的就是static(静态),今天我们总结一下它的用法吧
- 随着类的加载而加载。
- 优于对象而存在。
- 修饰的成员被所有成员共享。
- 可不创建对象,直接可被调用。
顾名思义, static(静态)随着类加载只能加载一次,分配空间也是只能分配一次,就好比是一个类是一个父亲,static是父亲所拥有的的财富,只有父亲出现的时候父亲所用的财富才会跟着出现,对象就好比是类的儿子,父亲的财富被儿子们共享,也可以单独给父亲使用,而不是某个儿子所私有的财产。这样说,大家应该别有一番领悟。
注意:静态的只能调用静态变量,非静态的可以调用静态和非静态的变量。
代码块:
1.静态代码块
2.实际代码块
package com.pratice.day2;
/*代码块:类似于一个没有名称的方法
分为实例代码块(非静态),静态代码块
实例代码块在每次创建对象时自动执行
静态代码块在类第一次加载时自动执行
*/
public class Dmk {
int a=20;
static int b=60;
{
System.out.println("实际代码块"+a);
}
{
System.out.println("实际代码块"+b);
}
static{
System.out.println("静态代码块"+b);
}
static{
System.out.println("静态代码块"+b);
}
}
package com.pratice.day2;
public class Dt {
public static void main(String[] args) {
System.out.println(Dmk.b);//执行静态代码块
new Dmk();//先类后对象,类只加载一次
new Dmk();
}
}
类加载时静态代码块按照从上自下的顺序依次加载,对象加载完之后,非静态代码块从上自下依次加载。