static 【重点】

static 【重点】

1. .class字节码文件加载
游戏加载,Loading...过程,就是在准备当前游戏执行所需的所有资源。
.class字节码文件:
	二进制可执行文件。Java 工具在执行对应的 .class 字节码文件内容时,首先有一个【加载过程】。
	将当前程序所需的所有类型,文件加载到内存中,为执行程序准备。
2. static关键字
2.1 static 修饰成员变量
2.1.1 代码演示
class TypeA {
	/*
	 * 静态成员变量 数据类型为 int 类型
	 */
	public static int num = 10;
	/*
	 * 非静态成员变量
	 */
	public int test = 20;
}

public class Demo1 {
	public static void main(String[] args) {
		TypeA typeA = new TypeA();
		
		System.out.println(typeA.test);
		/*
		 * The static field TypeA.num should be accessed in a static way
		 * TypeA 类内 static 修饰静态成员变量 num 应该使用静态方法操作
		 */
		System.out.println(typeA.num);
		/*
		 * 通过 TypeA 类名直接调用 static 修饰静态成员变量,代码运行成功,没有任何警告!!!
		 * 【蛛丝马迹】静态成员变量和类对象无关!!! 没有对象
		 * static 修饰的静态成员变量 ==> 类变量
		 */
		System.out.println(TypeA.num);
	}
}
class TypeB {
	/*
	 * 静态成员变量
	 */
	public static int num = 10;
}

public class Demo2 {
	public static void main(String[] args) {
		/*
		 * 静态成员变量在程序的加载阶段已经准备就绪,可以通过类名使用。
		 * 目前代码执行过程中,没有 TypeB 对象
		 * 【蛛丝马迹】静态成员变量就绪时间早于类对象创建
		 */
		System.out.println(TypeB.num);
		
		if (true) {
			/*
			 * 创建 TypeB 类对象有且只在 if 大括号以内有效!!!
			 * 大括号之外没有 TypeB 对象 ==> 超出大括号范围 TypeB 对象已销毁!!!
			 */
			TypeB typeB = new TypeB();
			System.out.println(typeB);
		}
	
		/*
		 * 静态成员变量在 TypeB 对象销毁之后,依然可以通过类名直接调用操作使用,
		 * 【蛛丝马迹】静态成员变量销毁时间晚于类对象销毁
		 * 
		 * 【小总结】静态成员变量来得比对象早,走的比对象晚。生存周期不同!!!两者无关,
		 * 【没有对象】
		 */
		System.out.println(TypeB.num);
	}
}
2.1.2 静态成员变量生活案例分析
1. 共享单车
	a. 共享单车属于运营公司,与个人无关。
	b. 共享单车个人有使用权,没有所有权。
	c. 共享单车存放于公共区域,不占用个人空间
	d. 共享单车如果损坏,所有人都无法使用,是一个【共享资源】
	e. 你来到这个城市,共享单车在这里,你离开这个城市,共享单车依然在这里。

2. 饮水机
	a. 饮水机属于千锋教育,与个人无关
	b. 饮水机个人有使用权,没有所有权
	c. 饮水机在公共区域,不占用个人空间
	d. 饮水机出现问题,大家都是无法使用,是一个【共享资源】
	e. 你来到千锋之前,饮水机在这里,你从千锋毕业之后,饮水机依然在这里。
2.1.3 静态成员变量特征【难点】
1. 静态成员变量建议通过类名调用,不推荐使用类对象调用,因为静态成员变量和对象无关,【没有对象】。
2. 静态成员变量在类文件(.class字节码文件)加载到内存的过程中,已经准备就绪。
	例如:
		游戏开始之前的资源加载,画面,建筑,双方连接。。。
		校区你们入学之前,校区的准备工作必须完成,饮水机,电,网...
3. 静态成员变量存在与内存的【数据区】,不归属于类对象,因为类对象在内存的【堆区】。两者内存空间位置不同,两者没有关系。【没有对象】
	例如:
		共享单车的存放位置。
		饮水机所在存放位置。

4. 静态成员变量早于类对象出现,晚于类对象销毁,生存周期不同。两者合作不便,两者没有关系。【没有对象】
5. 静态成员变量是一个【共享资源】,一处修改,处处受影响。
6. 静态成员变量在整个程序中,对于当前类而言有且只有一个!!!独一份!!!
7. 静态成员变量常用于代码中:
	常量定义,共享数据定义,唯一数据标记!!!变量两大特征【共享性,持久性】
2.2 static 修饰成员方法
2.2.1 代码演示
package com.qfedu.b_staticmethod;

class TypeA {
	// 非静态成员
	public int num = 10;
	
	public void test() {
		System.out.println("非静态修饰成员方法");
	}
	
	// 静态成员
	public static int staticNumber = 200;
	
	public static void test2() {
		System.out.println("静态成员方法");
	}
	
	public static void testStaticMethod() {
		/*
		 * Cannot make a static reference to the non-static field num
		 * 在静态方法中不允许直接调用类内的非静态成员变量。【没有对象】
		 */
		// System.out.println(num);
		/*
		 * Cannot make a static reference to the non-static method test() from the type TypeA
		 * 在静态成员方法中不允许直接调用类内的非静态成员方法。【没有对象】
		 */
		// test();
		
		/*
		 * 难兄难弟,互不嫌弃
		 * 静态成员方法中可以直接调用类内的其他静态成员
		 */
		System.out.println(staticNumber);
		test2();
		System.out.println("静态修饰成员方法");
	}
}

public class Demo1 {
	public static void main(String[] args) {
		TypeA typeA = new TypeA();
		
		/*
		 * The static method testStaticMethod() from the type 
		 * TypeA should be accessed in a static way
		 * TypeA 类中的静态修饰成员方法 testStaticMethod() 应该通过静态方法访问
		 */
		typeA.testStaticMethod();
		/*
		 * 通过类名调用静态成员方法,没有任何的警告!!!
		 * 使用类对象调用静态成员方法有警告提示,类名调用符合语法建议,IDE工具在提示静态城方法和对象无关。【没有对象】
		 */
		TypeA.testStaticMethod();
	}
}
2.2.2 静态成员方法特征总结
1. 静态成员方法推荐使用类名直接调用,不推荐使用类对象调用,IDE工具提示静态成员方法和类对象无关。【没有对象】
2. 静态成员方法中不可以直接使用类内的非静态成员。【没有对象】
	非静态成员(成员变量和成员方法),是需要创建对象之后,才可以使用,具有一定的对象特征。
3. 静态成员方法中可以直接使用类内的其他静态成员。【难兄难弟,互不嫌弃】
4. 静态成员方法是随着类文件的加载过程中,已经具备执行能力!!!方法执行所有的必要要素都准备就绪。
	权限修饰符,返回值类型,方法名,形式参数列表,方法体内容。
	案例分析
		static修饰方法是否可以使用 abstract 关键字修饰?
		static修饰方法需要在加载阶段具备执行能力,明确有方法体。abstract 修饰方法没有方法体!!!
		两者无法合作,static修饰方法不可以用 abstract 关键字,abstract 修饰符方法不可以用 static。
5. 静态成员方法在类文件加载阶段,在内存的【方法区】准备就绪,早于类对象出现,JVM在退出程序的过程中,首先销毁所有的类对象,最后再来清理【方法区】静态成员方法占用的内存空间数据。静态成员方法和类对象生存周期不同,两者没有关系。【没有对象】
6. 静态成员方法执行效率高!!!
	省内存
		静态成员方法直接通过类名调用,无需对象。类对象占用的内存【堆区】空间,省了!!!
	省时间
		1. 创建对象需要时间
		2. 销毁对象需要时间
		静态成员方法不需要这部分时间,省了!!!
2.2.3 静态成员方法之工具类
数组工具类:
	ArraysArrays 工具类中,存在大量 static 修饰的静态成员方法,所有方法通过类名可以直接调用,方法运行所需参数全部通过方法【形式参数列表】传入。
	String toString(int[] arr);int 类型数组转换成 String 字符串形式描述,所有的元素内容在中括号中包含,每一个元素之间使用 , + 
		空格隔开
		例如:
			int[] arr = {1, 3, 5};
			String str = Arrays.toString(arr);
			str ==> "[1, 3, 5]";
	
	void sort(int[] arr);
		Arrays工具类中的优化高效的【快速排序】,默认升序!!!
	
	int binarySearch(int[] arr, int num);
		二分法查询
		方法调用前,要求参数数组必须是已经被【sort】执行的。参数数组必须是有序数组。找到返回值大于等于 0 未找
		到返回【负数】
package com.qfedu.b_staticmethod;

import java.util.Arrays;

/*
 * Arrays 工具类演示
 */
public class Demo2 {
	public static void main(String[] args) {
		int[] arr = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
		
		// 1. toString 数组内容 转字符串信息描述
		String string = Arrays.toString(arr);
		System.out.println(string);
	
		// 2. sort 排序,默认升序
		Arrays.sort(arr);
		String string2 = Arrays.toString(arr);
		System.out.println(string2);
		
		// 3. binarySearch 二分法查询
		int index = Arrays.binarySearch(arr, 15);
		System.out.println(index);
	}
}
2.3 static 代码块
2.3.1 常见代码块
构造代码块
	{}class 大括号以内
局部代码块
	{} 在 方法大括号以内
静态代码块
	static {}class 大括号以内
2.3.2 构造代码块
package com.qfedu.c_staticblock;

class Type {
	public Type() {
		System.out.println("父类构造方法");
	}
}

class Person extends Type {
	private String name;
	private int age;
	
	/*
	 * 构造代码块,一般在 成员变量 之后,构造方法 之前.
	 * 执行当前类构造方法,和 new 关键字一起使用,用于创建对象。无论哪一个构造方法执行,
	 * 构造代码块内容一定会执行,并且先于构造方法执行。
	 * 
	 * Java编译器在编译 Java 代码 ==> .class 字节码文件的过程中,首先会将所有的构造
	 * 代码块内容放置于构造方法原内容的上方【80%正确】,按照代码的顺序流程执行,首先会执行
	 * 构造代码块内容
	 * 
	 * 一般用于构造方法统一功能的封装操作!!!
	 */
	{
		System.out.println("构造代码块执行....");
	}
	
	public Person() {
		System.out.println("无参数构造方法\n");
	}

	public Person(String name) {
		this.name = name;
		System.out.println("String类型参数构造方法\n");
	}
	
	public Person(int age) {
		this.age = age;
		System.out.println("int类型参数构造方法\n");
	}

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
		System.out.println("String, int类型参数构造方法\n");
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
}

public class Demo1 {
	public static void main(String[] args) {
		Person person = new Person();
		Person person2 = new Person(10);
		Person person3 = new Person("张三");
		Person person4 = new Person("张三", 10);
	}
}
2.3.3 局部代码块
使用不多
package com.qfedu.c_staticblock;

public class Demo2 {
	public static void main(String[] args) {
		int num = 10;
		
		/*
		 * 老技术!!!
		 *  局部代码块!!!
		 *  局部代码块可以压缩局部变量的生存周期!!!提高内存复用率
		 */
		{
			int num2 = 20;
		}
		
		System.out.println(num);
//		System.out.println(num2);
	}
	
}
2.3.4 静态代码块
package com.qfedu.c_staticblock;

/*
 * static 修饰静态代码块特征:
 * 		1. 静态代码块在类文件加载过程中,有且只执行一次!!!
 *		2. 静态代码块不可以直接使用类内的非静态成员 【没有对象】
 *		3. 静态代码块可以直接使用类内的静态成员【难兄难弟】
 *		4. 静态代码块常用语项目启动过程中初始化操作
 *			例如:
 *				加载必要资源,读取必要配置文件,加载安装必要驱动
 */
class SingleDog {
	public int num = 10;
	
	public void testNoneStatic() {
		System.out.println("非静态成员方法");
	}
	
	public static int value = 10;
	
	static {
		/*
		 * Cannot make a static reference to the non-static field num
		 * 静态代码块中不能直接使用非静态成员变量。【没有对象】
		 */
		// System.out.println(num); 
		/*
		 * Cannot make a static reference to the non-static method testNoneStatic() from the type SingleDog
		 * 静态代码块中不能直接使用非静态成员方法。【没有对象】
		 */
		// testNoneStatic();
		
		/*
		 * 难兄难弟,互不嫌弃
		 * 静态代码块中,可以直接使用类内的其他静态成员
		 */
		System.out.println(value);
		test();
		System.out.println("路见不平一声吼,大哥是个单身狗"); 
	}
	
	public static void test() {
		System.out.println("静态成员方法");
	}
}

public class Demo3 {
	public static void main(String[] args) {
		SingleDog.test();
		
		System.out.println("main方法执行........"); 
	}
}

作业
package com.qfedu.c_staticblock;

public class Demo4 {
	static Demo4 d1 = new Demo4();
	static Demo4 d2 = new Demo4();
	
	{
		System.out.println("Constructor block running....");
	}
	
	static {
		System.out.println("static block running...");
	}
	
	public Demo4() {
		System.out.println("Constructor running...");
	}
	
	public static void main(String[] args) {
		Demo4 demo4 = new Demo4();
	}
	/*
	 * 执行流程是什么,为什么这样执行!!!
	 */
}

.qfedu.c_staticblock;

public class Demo4 {
static Demo4 d1 = new Demo4();
static Demo4 d2 = new Demo4();

{
	System.out.println("Constructor block running....");
}

static {
	System.out.println("static block running...");
}

public Demo4() {
	System.out.println("Constructor running...");
}

public static void main(String[] args) {
	Demo4 demo4 = new Demo4();
}
/*
 * 执行流程是什么,为什么这样执行!!!
 */

}






















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员子衿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值