Static
static 的中文意思是"静态",它可以修饰成员变量、成员方法
1. Static 修饰成员变量
- static 修饰的成员变量,也称之为"类变量"
- 类变量它是属于类的,与类一起加载,在内存中只有一份,会被类的所有对象共享
- 无 static 修饰的成员变量,称之为 " 实例变量 (对象变量) "
- 实例变量 (对象变量) 是属于对象的,每个对象中都有一份
public class HelloWorld {public static void main(String[] args) {Human.name = "人类"; // 直接通过 "类名.类变量名" 的方式来访问(推荐此方法)Human obj = new Human();obj.name = "人才"; // 也可以通过 "对象.类变量名" 的方式访问,但是不推荐此方法!}
}class Human {// 类变量static String name;// 实例变量(对象的变量)int age;
}
2. 类变量的使用场景
在开发中,如果某个数据只需要一份,且希望能够被共享 (访问、修改),则该数据可以定义成类变量来记住。
import java.util.ArrayList;public class HelloWorld {public static void main(String[] args) {// 创建一个集合,用来存放对象ArrayList list = new ArrayList();System.out.println(Human.number); // 0for (int i = 0; i < 5; i++) {Human obj = new Human();list.add(obj);}System.out.println(Human.number); // 5}
}class Human {// 类变量static int number; // 没必要自己手动初始化,因为默认自动初始化为 0public Human() {Human.number++;// 在同一个类中,访问自己类的类变量,可以省略不写前面的 Human// 即:可以将 Human.number++ 写成 number++}
}
3. static 修饰成员方法
- 类方法:有 static 修饰的成员方法,属于类
- 实例方法:无 static 修饰的方法,属于对象
public class HelloWorld {public static void main(String[] args) {Human.printHelloWorld(); // 直接通过"类名.类方法名"进行调用(推荐使用此方法)Human obj = new Human();obj.printHelloWorld(); // 不推荐使用此方法obj.printGood();}
}class Human {// 类方法public static void printHelloWorld() {System.out.println("Hello World");}// 实例方法(对象的方法)public void printGood() {System.out.println("Good");}
}
4. 类方法的使用场景
-
类方法最常见的应用常见是做工具类
-
什么是工具类?
简单的说,就是创建一个类,在里面写一些功能,方便别人去调用你写的工具;
而在工具类中,使用的方法都是一些类方法,而不是实例方法
因此,工具类没有创建对象的需求,建议将工具类的构造器进行私有,从而禁止他人创建对象
另外要注意的是,一般情况下,每个方法都是用来完成一个功能的。
-
为什么工具类中的方法要使用类方法,而不用实例方法?
首先,实例方法确实也能够实现做工具类,但是!实例方法需要创建对象来调用,而如果大费周章创建了一个对象,却只是为了用它来调用实例方法,在操作上看,这是多此一举,在内存上看,它还浪费了内存。
-
使用类方法设计工具类的好处
提高了代码的复用;调用方便,提高了开发效率。
5. 代码块
概述:代码块是类的5大成分之一(成员变量、方法、构造器、代码块、内部类)
代码块分两种
-
静态代码块:static { }
特点:类加载时自动执行,由于类只会加载一次,所以静态代码块也只会执行一次
作用:完成类的初始化,例如:对类变量的初始化赋值
-
实例代码块:{ }
特定:每次创建对象时,都会先执行实例代码块,再执行构造器
作用:和构造器一样,都是用来完成对象的初始化操作的,例如:对实例变量进行初始化赋值
public class HelloWorld {public static void main(String[] args) {// 先加载一次类,执行一次 static{},再同步执行 Human.numberSystem.out.println(Human.number);System.out.println(Human.number);System.out.println(Human.number);// 实例代码块——功能演示Human obj = new Human();Human obj2 = new Human(25);// 程序运行结果:/*静态代码块执行了~~111警告!有人创建了对象!对象内存地址: login.Human@682a0b20此人使用了[无参]构造器创建对象警告!有人创建了对象!对象内存地址: login.Human@3d075dc0此人使用了[含参]构造器创建对象*/}
}class Human {static int number;// 静态代码块static {System.out.println("静态代码块执行了~~");number++;}// 实例代码块{System.out.println("警告!有人创建了对象!对象内存地址: " + this);}public Human() {System.out.println("此人使用了[无参]构造器创建对象");}public Human(int age) {System.out.println("此人使用了[含参]构造器创建对象");}
}
6. 单例设计模式
什么是设计模式?
- 一个问题通常有n种解法,其中肯定是有一种最优解法,这种解法被人总结出来了,称之为设计模式
- 设计模式有20多种,对应20多种软件开发中会遇到的问题
单例设计模式
- 要求:确保一个类只有一个对象
- 饿汉式单例:拿对象时,对象早就创建好了
- 懒汉式单例:拿对象时,才开始创建对象
- …
// 饿汉式单例public class HelloWorld {public static void main(String[] args) {Human obj1 = Human.getObj();Human obj2 = Human.getObj();System.out.println(obj1 == obj2); // true}
}class Human {private static Human obj = new Human(); // 此行代码只会在类加载时,执行一次private Human() {}public static Human getObj() {return obj;}
}
// 懒汉式单例public class HelloWorld {public static void main(String[] args) {Human obj1 = Human.getObj();Human obj2 = Human.getObj();System.out.println(obj1 == obj2); // true}
}class Human {private static Human obj;private Human() {}public static Human getObj() {if (Human.obj == null) {obj = new Human();}return obj;}
}