文章目录
- 1.访问控制符
- 2.静态字段/方法/代码块
- 2.1 静态字段
- 2.2 静态常量
- 2.3 静态方法
- 2.4 特点
- 2.5 static入门案例
- 2.6 静态的调用关系
- 2.7 静态代码块
- 2.7.1 格式
- 2.7.2 特性:
- 2.7.3 执行顺序
- 2.7.4 案例练习
- 3.final的概念
- 3.1 特点
- 3.2 final入门案例
1.访问控制符
在JAVA中,我们通过访问控制符来控制所属类和方法的访问权限。
上图表明的不同访问控制符修饰的类或方法在不同位置的访问权限问题。其中默认代表不写任何修饰符情况下的权限。
2.静态字段/方法/代码块
在前面的一些程序中,大家可以发现,所有的main方法都包含static修饰符,其代表当前方法为静态方法,当前static修饰符也可以用在类的修饰中。
2.1 静态字段
如果将一个字段定义为static,每个类只有一个这样的字段。而对于非静态的实例字段,每个对象都有自己的一个副本。例如,假设需要给每个员工赋予唯一的标识码。
class YuanGong{
private static int nextId = 1;
private int id;
}
例如上方的代码,这个类的所有实例将共享一个nextId字段,但创建的每一个YuanGong对象都有一个自己的id字段,如果有100个YuanGong对象,那么就有100个id字段会被创建,分别对应每一个对象。
但是只有一个静态字段nextId存在,即使没有YuanGong对象的存在,静态字段YuanGong也存在,其属于类,而不属于任何一个单个的对象。
2.2 静态常量
在日常开发中,静态变量使用是比较少的,我们更多的是使用静态常量。
如在后续的多线程问题案例中,多个售票窗口同时售卖同一类型的票,在创建对个窗口对象时,如果使用普通常量创建,会导致同时创建多个静态的票,原本一共只有100张票,创建对象后则会变成多个100张,此时我们便可以使用静态常量来创建,避免这个问题。
2.3 静态方法
静态方法是不在对象上执行的方法。例如前边实例中的main方法。
在以下俩种情况下,可以使用静态方法:
- 方法不需要访问对象状态,因为它需要的参数都是通过显示参数提供的。
- 方法只需要访问类的静态字段
同时需要注意,main方法不对任何对象进行操作,事实上,在启动程序时还没有任何对象创建。静态的main方法将执行并构建程序所需要的对象,构建对象所需要的参数,都是显示参数提供的。
2.4 特点
- static可以修饰成员变量与成员方法
- 被static修饰的资源称为静态资源,静态资源也叫做类资源
- 静态资源随着类的加载而加载,是最先加载的,优先于对象进行加载
- 静态资源可以通过类名直接调用,所以也被称作类资源
- 静态资源只要加载一次,就会一直存在,不再开辟新空间, 直到类消失才一起消失
- 静态资源被全局所有对象共享,全局唯一,值只有一份
- 静态只能调用静态,非静态可以随意调用
- static静态区域内不能和this或者super共用,因为有static时可能还没有对象
2.5 static入门案例
package partTwo;
/* 本类用于测试静态static关键字*/
public class TestStatic {
public static void main(String[] args) {
Fruit f = new Fruit();
f.grow();
f.clean(); //没有提示需要自己写
System.out.println(f.weight);
System.out.println(f.kind); //没有提示需要自己写
Fruit f2 = new Fruit();
//我们可以通过类名直接调用静态资源,而且这个IDEA会提示
Fruit.clean();
System.out.println(Fruit.kind);
/* 静态资源在内存中只有一份,被全局所有对象共享
* 所以我们会发现,通过任意一种方式修改了静态变量的值以后,其他任何方式查看,都是修改后的值*/
Fruit.kind = "苹果";
System.out.println(Fruit.kind);
f.kind = "香蕉";
System.out.println(Fruit.kind);
System.out.println(f.kind);
System.out.println(f2.kind);
f2.kind = "猕猴桃";
System.out.println(Fruit.kind);
System.out.println(f.kind);
System.out.println(f2.kind);
}
}
/* 0.被stati修饰的资源称作静态资源
* 静态资源是随着类加载而加载到内存中的,比对象优先进入内存
* 所以静态资源可以通过类名直接调用,即使没有创建对象,也可以调用*/
//1.创建一个水果类
class Fruit{
/* 1.可以用static修饰属性吗 可以*/
//2.定义属性
static String kind; //种类
double weight; //重量
//3.定义普通方法
/* 2.可以用static修饰方法吗? 可以*/
static public void clean(){
System.out.println("洗洗更健康");
}
public void grow(){
System.out.println("这个水果长的真大");
}
}
- 没有提示需要自己写的部分为idea智能提醒,此处不是最高效的调用方式;
静态资源可以通过类名直接调用,不需要创建对象后再调用; - 静态资源在内存中只有一份,被全局所有对象共享
所以我们会发现,通过任意一种方式修改了静态变量的值以后,其他任何方式查看,都是修改后的值
2.6 静态的调用关系
- 非静态资源可以调用静态资源也可以调用非静态资源;
- 静态资源只能调用静态资源
package partTwo;
/* 本类用于测试静态的调用关系*/
public class TestStatic2 {
public static void main(String[] args) {
Teacher2 t = new Teacher2();
t.ready();
System.out.println(t.name);
}
}
//创建一个老师类
class Teacher2{
//定义属性与方法
String name;
static int age;
public void ready(){
System.out.println("正在备课中。。。");
/* 普通资源能否调用静态资源? 可以*/
System.out.println(age);
teach();
}
//定义静态方法
public static void teach(){
System.out.println("正在授课中");
/* 静态资源能否调用普通资源? 不可以*/
//System.out.println(name);
//ready();
}
public static void eat(){
System.out.println("干饭人...");
/* 静态资源能否调用静态资源 可以*/
System.out.println(age);
teach();
}
}
2.7 静态代码块
2.7.1 格式
static{ }
2.7.2 特性:
- 位置:类里方法外
- 执行时机:静态代码块也属于静态资源,随着类的加载而加载,优先于对象加载,并且只加载一次
- 作用:用于加载那些需要第一时间就加载,并且只需要加载一次的资源,常用量初始化
2.7.3 执行顺序
静态代码块 > 构造代码块 > 构造方法 > 普通方法 > 局部代码块
2.7.4 案例练习
package partTwo;
/* 本类用来测试静态代码块*/
public class TestStatic3 {
public static void main(String[] args) {
Person2 p = new Person2();
p.play();
Person p2 = new Person();
}
}
// 1.创建Person类
class Person2{
//6.创建静态代码块
static {
/* 静态代码块stati
* 位置:类里方法外
* 执行时机:静态代码块也属于静态资源,随着类的加载而加载,优先于对象加载,并且只加载一次
* 作用:用于加载那些需要第一时间就加载,并且只需要加载一次的资源,常用量初始化*/
System.out.println("我是静态代码块");
}
//2.创建构造代码块
{
//位置:类里方法外
//执行时机:创建对象时执行,优先构造方法执行
//作用:用于提取所有构造方法的共性功能
System.out.println("我是一个构造代码块");
}
//3.创建无参构造方式
public Person2(){
}
//4.创建普通方法play
public void play(){
System.out.println("我爱玩代码");
//5.创建局部代码块
{
//位置:方法里
//执行时机:调用其所处的方法时执行
//作用:用于控制变量的作用范围
System.out.println("我是一个局部代码块");
}
}
}
结论:执行顺序:静态代码块 --> 构造代码块 --> 构造方法 --> 局部代码块
- 静态代码块:在类加载时就加载,并且只被加载一次,一般用于项目的初始化
- 构造代码块:在创建对象时会自动调用,每次创建对象都会被调用,提取构造共性
- 局部代码块:方法里的代码块,限制局部变量的范围
3.final的概念
- 是java提供的一个关键字
- final是最终的意思
- final可以修饰类,方法,字段(属性)
初衷:java出现继承后,子类可以更改父类的功能,当父类功能不许子类改变时,可以利用final关键字修饰父类。
3.1 特点
- 被final修饰的类,不能被继承
- 被final修饰的方法,不能被重写
- 被final修饰的字段是个常量,值不能被修改
- 常量的定义形式:final 数据类型 常量名 = 值
3.2 final入门案例
package partTwo;
/* 本类用于测试final关键字*/
public class TestFinal {
public static void main(String[] args) {
Father f = new Father();
f.work();
Son s = new Son();
s.work();
System.out.println(s.a);
// s.a = 100; 报错,不可以给被final修饰的变量a重新赋值
}
}
/* 1.final可以用来修饰类吗? 可以
* 被final 修饰的类是最终类,不可以被继承
* 可以把final修饰的类看成树结构中的叶子节点*/
//1.定义父类
//3.测试类被final修饰
//final class Father{
class Father{
/* 2.final可以用来修饰方法吗? 可以
* 被final修饰的方法是这个方法最终的实现,不可以被重写*/
//4. 测试方法被final修饰
//public final void work(){
public void work(){
System.out.println("在工厂里上班");
}
}
//2.定义子类
//class Son extends Father{ 报错,不可以继承一个被final修饰的类
class Son extends Father{
/* 3.final可以用来修饰变量吗?
* 被final修饰的是常量,值不可以被修改
* 注意:定义常量时必须要赋值,不赋值就报错*/
final int a=10 ;
//5.重写父类方法
public void work(){
System.out.println("在家玩游戏");
}
}