目录
静态关键字:static
static关键字的作用
static是静态的意思,可以修饰成员变量和成员方法。
static修饰成员变量表示该成员变量只在内存中只存储一份,可以被共享访问、修改。
总结
static修饰成员变量的内存原理
类执行的时候加入方法区的同时,会在堆内存中开辟这个类的静态变量区。
static修饰成员方法的基本用法
使用场景:
总结
static修饰成员方法的内存原理
先加载类,类进入方法区。类里面加载静态方法,study()方法没加载是因为属于对象,不可访问,所以没出现在方法区,而静态方法(可访问状态)和类一起优先加载。
main方法进入
方法加载到栈里面跑。
对象创建出来后,实例方法就加载进来,让这个对象指向。这个对象也可以指向静态区的方法(静态方法是共享的,所有人都可以访问)。
static的注意事项
package com.ithema.d1_static;
public class Test3 {
/**
* 静态成员
*/
public static int onLineNumber = 10;
// 实例成员变量
private String name;
public void run() {
System.out.println(name + "跑得快~~");
}
public static void test2() {
System.out.println("==test2==");
}
// 3、静态方法中不能出现this关键字
public static void tes3() {
//System.out.println(this);//this只能带表当前对象!!静态方法可以不用对象
}
// 2、实例方法可以直接访问静态成员,也可以访问实例成员
public void go() {
System.out.println(Test3.onLineNumber);
System.out.println(onLineNumber);
test2();//=Test3.test2();
System.out.println(name);
System.out.println(this.name);
System.out.println(this);
run();//go()方法需要对象调用,然受在调用run()方法
}
// 1、静态方法可以直接访问静态成员,不能访问实例成员。
public static void test() {
System.out.println(Test3.onLineNumber);
System.out.println(onLineNumber);
test2();//=Test3.test2();
// System.out.println(name); //不能直接访问实例成员.
//run();
}
public static void main(String[] args) {
}
}
static实际应用案例:定义工具类
工具类中定义的都是一些静态方法,每个方法都是以完成一个共用的功能为目的。
package com.itheima.d2_static_util;
import java.util.Random;
public class Login {
public static void main(String[] args) {
// 验证码:
String code = "";
//2.定义一个变量记住全部验证码字符。
String data = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
//3.定义一个循环生成几个随机索引,去得到几个字符
Random r = new Random();
for (int i = 0; i < 5; i++) {
//4.获取随机索引对应的字符,连接给code
int index = r.nextInt(data.length());
code += data.charAt(index);
}//for
System.out.println("验证码:" + code);
}
}
总结
练习:定义数组工具类
package com.itheima.d2_static_util;
public class ArraysUtils {
/**
* 把它的构造器私有化
*/
private ArraysUtils() {
}
/**
* 静态方法,工具方法
*/
public static String toString(int[] arr) {
//1.一些校验
if (arr == null) {
return null;
}
//2.拼接内容并返回
String result = "[";
for (int i = 0; i < arr.length; i++) {
result += (i == arr.length - 1 ? arr[i] : arr[i] + ",");
}//for
result += "]";
return result;
}
}
package com.itheima.d2_static_util;
public class TestDemo2 {
public static void main(String[] args) {
int [] arr =null;
int [] arr1 = {};
int [] arr2 ={12,23,44,99};
System.out.println(ArraysUtils.toString(arr));
System.out.println(ArraysUtils.toString(arr1));
System.out.println(ArraysUtils.toString(arr2));
}
}
static应用知识:代码块
代码块的分类、作用
静态代码块:
package com.itheima.d3_static_code;
public class StaticDemo3 {
public static String schoolName;
public static void main(String[] args) {
// 目标:学习静态代码块的特点、基本作用
System.out.println("=========main方法被执行输出===========");
System.out.println(schoolName);
}
/**
静态代码块
特点:与类一起加载,自动触发一次,优先执行
作用:可以在程序加载时进行静态数据的初始化操作(准备内容)
*/
static {
System.out.println("==静态代码块被触发执行==");
schoolName="黑马";
}
}
构造代码块(了解,用的少):
package com.itheima.d3_static_code;
public class StaticDemo2 {
// 目标:学习构造代码块的特点、基本作用
private String name;
public StaticDemo2(){
System.out.println("==无参构造器被触发执行==");
}
/**
属于对象的,与对象一起加载,自动触发执行。
*/ {
name = "张三";
System.out.println("==构造代码块被触发执行==");
}
public static void main(String[] args) {
StaticDemo2 s1 = new StaticDemo2();
System.out.println(s1.name);
StaticDemo2 s2 = new StaticDemo2();
System.out.println(s2.name);
}
}
静态代码块的应用案例:斗地主游戏
package com.itheima.d3_static_code;
import java.util.ArrayList;
public class StaticTest3 {
/**
* 1.定义一个集合
*/
public static ArrayList<String> cards = new ArrayList<>();
/**
* 2、在游戏启动之前需要准备好54张牌放进去,使用静态代码块进行初始化
*/
static {
// 3、加载54张牌进去。
String[] size = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};
// 4、准备4种花色:类型确定,个数确定了
String[] colors = {"♠", "♥", "♣", "♦"};
for (int i = 0; i < size.length; i++) {
// sizes[i]
for (int j = 0; j < colors.length; j++) {
//一张牌
//colors[j]
String card = size[i] + colors[j];
cards.add(card);
}
}//for
cards.add("小🃏");
cards.add("大🃏");
}
public static void main(String[] args) {
System.out.println("新牌:"+cards);
}
}
总结
static应用知识:单例设计模式
package com.itheima.d4_singleinstance;
/**
* 目标:学会使用饿汉单例模式设计单例类
*/
public class SingleInstance {
/**
* 2.饿汉单例是在获取对象前,对象已经提前准备好了一个。
* 这个对象只能是一个,所以定义静态成员变量记住。
*/
public static SingleInstance instance = new SingleInstance();
// public static int age = 21; 类比,上面代码和慈航代码逻辑是一样的
/**
* 1、必须私有构造器:私有构造器对外不能被访问。
*/
private SingleInstance() {
}
}
package com.itheima.d4_singleinstance;
import java.security.Signature;
public class Test1 {
public static void main(String[] args) {
SingleInstance s1 = SingleInstance.instance;
SingleInstance s2 = SingleInstance.instance;
System.out.println(s1==s2);//都是同一个对象
}
}
总结:
懒汉单例设计模式
package com.itheima.d4_singleinstance;
/**
* 目标:设计懒汉单例
*/
public class SingleInstance2 {
/**
* 2、定义一个静态的成员变量用于存储一个对象,一开始不要初始化对象,因为人家是懒汉
*/
private static SingleInstance2 instance;
/**
* 3、提供一个方法暴露,真正调用这个方法的时候才创建一个单例对象
*/
public static SingleInstance2 getInstance() {
if (instance == null) {
// 第一次来拿对象,为他做一个对象
instance=new SingleInstance2();
}
return instance;
}
/**
* 1、私有构造器啊
*/
private SingleInstance2() {
}
}
package com.itheima.d4_singleinstance;
public class Test2 {
public static void main(String[] args) {
SingleInstance2 s1 = SingleInstance2.getInstance();
SingleInstance2 s2 = SingleInstance2.getInstance();
System.out.println(s1==s2);
}
}