static修饰成员变量
- Java中的成员变量按照有无static修饰,分为两种 类变量和实例变量
- static修饰的成员变量成为类变量
- 类变量在计算机中只有一份,会被类的全部对象共享
- 实例变量,属于每个对象
package demo0314;
public class Student {
// 类变量
static String name;
// 实例变量
int age;
}
package demo0314;
public class Test {
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student();
// 类变量可以通过类名直接访问
// 类变量所有对象共享
// 类变量可以通过对象访问,且某个对象修改类变量后,其他对象的类变量也会发生改变
// 类变量推荐使用类名访问,而不是通过对象访问
Student.name = "abc";
System.out.println(s1.name);
System.out.println(Student.name);
System.out.println(s2.name);
s2.name = "cde";
System.out.println(s1.name);
System.out.println(Student.name);
System.out.println(s2.name);
// 没有static修饰的成为实例变量
// 实例变量只能通过对象访问,不能通过类名访问
// 某个对象修改了实例变量,不会影响刀其他对象
Student s3 = new Student();
Student s4 = new Student();
// Student.age = 10
s3.age = 50;
System.out.println(s3.age);
System.out.println(s4.age);
}
}
static修饰成员方法
- java中的成员方法根据有无static修饰分为两种类方法和实例方法
package demo0314;
public class Student {
// 类方法
public static void printHello(){
System.out.println("hello");
}
// 实例方法
public void printWorld(){
System.out.println("World" + this);
}
}
package demo0314;
public class Test {
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student();
// 类方法可以通过类名访问
// 类方法没有this变量,且所有对象都可以访问
// 类方法推荐使用通过类名访问
Student.printHello();
s1.printHello();
s2.printHello();
// 没有static修饰的成为实例方法
// 实例方法只能通过对象访问,不能通过类名访问
// 实例方法又this变量
Student s3 = new Student();
Student s4 = new Student();
// Student.printWorld();
s3.printWorld();
s4.printWorld();
s1.printWorld();
s2.printWorld();
}
}
类方法的应用场景: 工具类
- 工具类的优势: 调用方便,可以在任何地方通过类.方法来调用
- 相对于实例方法的优势: 因为每new一个对象,需要在堆内存中开辟一个空间,会造成内存的浪费;且多个实例名称,会造成混乱
- 类方法创建完成后,一次创建,多次使用,有效的节省了内存空间
- 构造器应该私有化,这样可以保障后面在使用的时候,无法new出新对象,进一步优化了内存的使用
package demo0314;
import java.util.Random;
public class Login {
private Login() {
}
public static String createCode(int n){
String code = "";
String data = "abcdefghijklmbopqrstuvwxyz1234567890";
Random r = new Random();
for (int i = 0; i < n; i++) {
int index = r.nextInt(data.length());
code += data.charAt(index);
}
return code;
}
}
package demo0314;
public class Test {
public static void main(String[] args) {
String code = Login.createCode(6);
System.out.println(code);
}
}
package demo0313;
import demo0314.Login;
public class Test {
public static void main(String[] args) {
String code = Login.createCode(4);
System.out.println(code);
}
}
static使用时的注意事项
- 类方法中可以直接访问类的成员,不能访问实例成员
- 实例方法既可以访问类成员,也可以访问实例成员
- 实例方法中可以出现this关键字,类方法中不可以出现。
static应用一: 静态代码块
1.代码块是类的5大成分之一:成员变量、构造器、方法、代码块、内部类
2.格式 static{}
3.特点: 类加载时自动执行,由于类只会加载一次,所以静态代码块也只会执行一次
4.作用: 完成类的初始化
package demo0319;
public class Student {
static int number = 80;
static String name;
// 静态代码块
static {
System.out.println("静态代码块运行了~~");
name = "童话";
}
}
package demo0319;
public class Test {
public static void main(String[] args) {
System.out.println(Student.number);
System.out.println(Student.number);
System.out.println(Student.number);
System.out.println(Student.name);
}
}
实例代码块
1.格式: {}
2.特定: 每次创建对象时,执行实例代码块,并在构造器前执行
3.作用: 和构造器一样,都是用来完成对象初始化的
4.构造器前执行
package demo0319;
public class Student {
static int number = 80;
public Student() {
System.out.println("无参数构造器执行了~~");
}
// 实例代码块
{
System.out.println("实例代码块执行了~~");
}
}
package demo0319;
public class Test {
public static void main(String[] args) {
System.out.println(Student.number);
System.out.println(Student.number);
System.out.println(Student.number);
// 创建对象时,实例代码块才会运行
Student s1 = new Student();
}
}
单例模式
- 作用: 确保一个类只有一个对象
- 写法
- 把类的构造器私有
- 定义一个类变量记住类的一个对象
- 定义一个类方法,返回对象
package demo0319;
public class Student {
// 创建一个类变量,记住当前类
private static Student s1 = new Student();
// 私有化类构造器
private Student(){
}
// 定义一个类方法返回类的对象
public static Student getObject(){
return s1;
}
}
package demo0319;
public class Test {
public static void main(String[] args) {
// 由于构造器私有,所以无法在外部创建对象
//Student s = new Student();
Student s1 = Student.getObject();
Student s2 = Student.getObject();
System.out.println(s1);
System.out.println(s2);
System.out.println(s1 == s2);
}
}
单例的实现形式
饿汉式单例
上面的代码就是饿汉式单例,获取对象时,对象早就被创建好了
懒汉式单例
- 特点: 获取对象时,才开始创建对象
package demo0319;
public class Student {
// 创建一个类变量,记住当前类
private static Student s1;
// 私有化类构造器
private Student(){
}
// 定义一个类方法,保证第一次调用时才创建对象,后续调用直接返回
public static Student getObject(){
if(s1 == null){
s1 = new Student();
System.out.println("第一次调用,创建对象~~");
}else {
System.out.println("后续调用,不在创建~~");
}
return s1;
}
}
package demo0319;
public class Test {
public static void main(String[] args) {
// 由于构造器私有,所以无法在外部创建对象
//Student s = new Student();
Student s1 = Student.getObject();
Student s2 = Student.getObject();
System.out.println(s1);
System.out.println(s2);
System.out.println(s1 == s2);
}
}