一、什么是static修饰符
1.static是静态意思,可以修饰成员变量和成员方法
2.static修饰成员变量表示该成员变量在内存中只存储一份,可以被共享访问,修改。
二、成员变量,成员方法的分类和访问分别是什么样的形式?
1.静态成员变量(有static修饰符修饰,属于类,只加载一次,可以共享访问)
访问格式:①类名.静态成员变量
②对象.静态成员变量(不推荐写法)
2.静态成员方法(有static修饰,属于类和对象共享)
访问格式:①类名.静态成员方法
②对象.静态成员方法(不推荐)
public class User{
private static String name;//定义静态成员变量
public static int getMax(int age1,int age2){
return age1 > age2 ? age1:age2;
}
public static void main(String[] args) {
//1.类名.静态成员变量
System.out.println(User.name);
//2.调用静态方法访问静态变量
System.out.println(User.getMax(19,11));//通过类名.方法名访问
System.out.println(getMax(12,20));//同一个类中 可以不写类名直接访问
}
}
3.实例成员变量(无static修饰符修饰,属于对象)
访问格式:对象名.实例成员变量
4.实例成员方法(无static修饰符修饰,属于对象)
访问格式:对象名.实例成员方法
Student s = new Student();
s.name = "孙悟空";
//3.对象.实例变量
System.out.println(s.name);
/*
实例方法 属于对象 只能用对象进行访问
*/
public void study(){
System.out.println(name+"正在打妖怪");
}
//4.对象.实例方法进行访问
s.study();//对象名.实例方法
//5、对象.静态方法(不推荐写法)
System.out.println(s.getMax(13,15));
三、两种成员变量,成员方法各自在什么情况下定义?
1、静态成员变量:表示在线人数等需要被共享的信息
2、静态成员方法:表示对象自己行为的,且方法中需要直接访问实例成员,则该方法必须申明成实例方法
3、实例成员变量:属于每个对象,且每个对象的该信息不同
4、如果该方法是以一个通用功能为目的,或者需要方便访问,则可以申明成静态方法
四、static访问修饰注意事项
/*
静态成员 包括静态成员方法和静态成员变量
*/
public static int onlineNumber = 3;//静态成员变量
public static void test2(){
System.out.println("我是静态方法test2");
}//静态成员方法
/*
实例成员 包括实例成员方法和实例成员变量
*/
private String name; //实例成员变量
public void run(){ //实例成员方法
System.out.println(name+"跑的很快");
}
1.静态方法只能访问静态的成员,不可以直接访问实例成员
//1.静态方法只能访问静态成员变量 不能 ”直接“ 访问实例成员(实例成员方法和实例成员变量)
public static void test(){
System.out.println(Test3.onlineNumber);//通过类名.方法名访问
System.out.println(onlineNumber);//同一个类中 可以不写类名直接访问
test2();//静态方法也可以访问另一个静态方法
// Test3 t = new Test3();//创建对象可以访问
// System.out.println(name); //不能 ”直接“ 访问,可以间接访问 对象名.静态成员变量 但是不推荐
// run();//同上 可以间接访问 对象名.静态成员方法
}
2.实例方法可以访问静态的成员,也可以访问实例成员
//2.实例方法可以访问静态成员,也可以访问实体成员
public void go(){
System.out.println(Test3.onlineNumber);//访问的静态成员变量
System.out.println(onlineNumber);//访问的静态成员变量
test2();//访问的静态成员方法
System.out.println(name);//访问的实体成员变量
run();//访问的实体成员方法
}
3.静态方法中不能出现this关键字
//3.静态方法中不可以存在this关键字
public static void to(){
// System.out.println(this);//this只能戴白当前对象 可以出现在实例方法中
}
五、static工具类
1、工具类是什么?有什么好处?
static工具类概念: 内部都是一些静态方法,每个方法完成一个功能
好处:一次编写,处处使用,提高了代码复用性
2、工具类有什么要求?
由于工具类不需要创建对象 ,故建议把其构造器私有化 显得专业严谨
六、static代码块
1、代码块概述
1.代码块是类的五大成分之一(成员变量,构造器,方法,代码块,内部类,定义在类中且在方法外,与方法平级
2.在Java类下,用{ }括起来的代码被称为代码块
2、代码块分类
1.静态代码块
格式:static{ }
特点:需要通过static关键字修饰,随着类的加载而加载,并且自动触发,只执行一次
使用场景:在类加载的时候做一些静态数据的初始化操作,以便后续使用
public class StaticDemo1 {
public static String schoolName;
public static ArrayList<String> list = new ArrayList<>();
/*
静态代码块:有static修饰,属于类 与类一起优先加载一次,自动触发执行
作用:可以用于初始化静态资源
*/
static {
System.out.println("静态代码块被执行了");
schoolName = "黑马";
list.add("1");
list.add("2");
}
public static void main(String[] args) {
//目标:理解静态代码块
System.out.println("main方法被执行调用了");
System.out.println(schoolName);
System.out.println(list);
}
}
2.构造代码块(使用较少)
格式:{ }
特点:每次创建对象,调用构造器执行时,都会执行该代码块中的代码,并且在构造器执行前执行
使用场景:初始化实例资源
public class StaticDemo2 {
private String name;
public StaticDemo2(){
System.out.println("无参构造器被触发了");
}
/*
实例代码块(构造器代码块):无static修饰 不属于类 每次构建对象时都会触发一次
作用:初始化实例资源
*/
{
name = "张三";
System.out.println("实例化代码块被触发了");
}
public static void main(String[] args) {
//目标:理解实例化代码块(构造器代码块)
System.out.println("main方法被触发了");
StaticDemo2 s = new StaticDemo2();
System.out.println(s.name);
StaticDemo2 s1 = new StaticDemo2();
System.out.println(s1.name);
}
}
3、静态代码块作用?
如果要在启动系统时对静态资源进行初始化,则建议使用静态代码块完成数据的初始化操作
七、单例模式
单例模式概念:可以保证系统中,应用该模式的这个类永远只有一个实例,即一个类永远只能创建一个对象
单例模式的实现方式:饿汉单例模式,懒汉单例模式
饿汉单例实现步骤:
①定义一个类,把构造器私有化
②定义一个静态变量存储一个对象
/*
使用饿汉单例实现单例类
*/
public class SingleInstance {
/*
2.饿汉单例是在获取对象前 对象已经提前准备好了一个
这个对象只能是一个 所以定义静态成员变量
*/
public static SingleInstance instance = new SingleInstance();
/*
1.必须把构造器私有化 对外不能随意构建对象
*/
private SingleInstance(){
}
public static void main(String[] args) {
SingleInstance s1 = SingleInstance.instance;
SingleInstance s2 = SingleInstance.instance;
System.out.println(s1 == s2);
}
}
懒汉单例实现步骤:
①定义一个类,把构造器私有化
②定义一个静态变量存储一个对象
③提供一个返回单例对象的方法
/*
2.定义一个静态成员变量负责存储一个对象
只加载一次,只有一份
注意:最好私有化,避免给别人挖坑
这样别人就不能用 类名.静态成员变量 进行访问,以免访问到的数据为null
*/
private static SingleInstance2 instance;
/*
3.提供一个方法 返回一个单例对象
*/
public static SingleInstance2 getInstance(){
if (instance == null){
//如果是第一次来拿对象 此时需要创建对象
instance = new SingleInstance2();
}
return instance;
}
public static void main(String[] args) {
SingleInstance2 s1 = SingleInstance2.getInstance();
SingleInstance2 s2 = SingleInstance2.getInstance();
System.out.println(s1);
System.out.println(s2);
//s1和s2的地址是一样的
}
/*
1.私有化其构造器
*/
private SingleInstance2(){
}