static - 静态的
- 理解:
静态的- 分类:
a. 静态属性
b. 静态方法
c. 静态代码块- static修饰属性
3.1 底层调用步骤:
类加载到方法区时,JVM会扫描该类的所有属性并把静态属性加载到 静态区中,静态属性属于类属性,该类所有的对象都共享该属性, 静态属性直到项目结束时才会被回收(静态属性的生命周期)
3.2 注意:静态属性使用类名调用
3.3 应用场景:该类每个对象共享的属性就用static修饰package com.qf.test05; public class Test01 { /** * 知识点:static修饰属性 * 应用场景:该类每个对象共享的属性就用static修饰 */ public static void main(String[] args) { Person p1 = new Person(); Person p2 = new Person(); p1.setName("小明"); p2.setName("小红"); System.out.println(p1.getName());//小明 System.out.println(p2.getName());//小红 // p1.star = "地球"; // p2.star = "火星"; // System.out.println(p1.star);--火星 // System.out.println(p2.star);--火星 //注意:静态属性属于每个对象共享的属性,直接使用类名调用 Person.star = "地球"; System.out.println(Person.star);//地球 } }
package com.qf.test05; /** * 编写一个类的步骤: * 1.属性 * 2.私有化属性 * 3.构造方法 - 无参构造、有参构造 * 4.get/set的 * 5.独有的方法 -- eat()、sleep()... */ public class Person { private String name; private char sex; private int age; static String star = "星球"; public Person() { } public Person(String name, char sex, int age) { this.name = name; this.sex = sex; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public char getSex() { return sex; } public void setSex(char sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public void eat(){ System.out.println(this.name + "吃饭饭"); } public void sleep(){ System.out.println(this.name + "睡觉觉"); } }
- static修饰方法
属于类方法,直接用类名调用
应用场景:工具类
package com.qf.test06; import com.qf.array.MyArrays; public class Test01 { /** * 知识点:static修饰方法 * 应用场景:工具类(该类中的方法都是静态的) */ public static void main(String[] args) { int[] arr = {5,72,9,4,21,1,6,3,81}; //排序 - 1,3,4,5,6,9,21,72,81 MyArrays.sort(arr); //查找 //返回值规则:搜索键的索引,如果它包含在数组中; 否则, (-(insertion point) - 1) //返回值规则:如果元素包含在数组中,返回下标;否则,(-(插入点) - 1) int index = MyArrays.binarySearch(arr,30); System.out.println("查找到元素的下标为:" + index); //拷贝数组 - [1, 3, 4, 5, 6, 9, 21, 72, 81, 0, 0, 0, 0, 0, 0] int[] newArr1 = MyArrays.copyOf(arr,15); //拷贝数组区间 - [4, 5, 6, 9, 21, 72, 81, 0, 0] int[] newArr2 = MyArrays.copyOfRange(newArr1,2,11);//(目标数组,开始下标-包含,结束下标-排他) //替换所有元素 - [888, 888, 888, 888, 888, 888, 888, 888, 888] MyArrays.fill(newArr2,888); //替换区间元素 MyArrays.fill(newArr2,2,4,666);//(目标数组,开始下标-包含,结束下标-排他,替换元素) //将数组转换为字符串 String str = MyArrays.toString(newArr2); System.out.println(str); } }
package com.qf.array; /** * 世上最牛逼的数组工具类 * @author xxx * @version 1.0 */ public class MyArrays { /** * 数组的排序 * @param arr 目标数组 */ public static void sort(int[] arr){ for (int i = 0; i < arr.length-1; i++) { for (int j = 0; j < arr.length-1-i; j++) { if(arr[j]>arr[j+1]){ int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } } /** * 数组的查找 * @param arr 目标数组 * @param key 要搜索的键 * @return 如果元素包含在数组中,返回下标;否则,(-(插入点) - 1) */ public static int binarySearch(int[] arr,int key){ int start = 0; int end = arr.length-1; while(start <= end){ int mid = (start+end)/2; if(key < arr[mid]){ end = mid-1; }else if(key > arr[mid]){ start = mid+1; }else{ return mid; } } return -start-1; } /** * 拷贝数组 * @param arr 目标数组 * @param newLength 拷贝长度 * @return 新数组 */ public static int[] copyOf(int[] arr,int newLength){ int copyLen = arr.length; if(copyLen > newLength){ copyLen = newLength; } int[] newArr = new int[newLength]; for (int i = 0; i < copyLen; i++) { newArr[i] = arr[i]; } return newArr; } /** * 拷贝区间数组 * @param arr 目标数组 * @param start 开始下标-包含 * @param end 结束下标-排他 * @return 新数组 */ public static int[] copyOfRange(int[] arr,int start,int end){ int length = end-start; int[] newArr = new int[length]; int index = 0; for (int i = start; i < end; i++) { newArr[index++] = arr[i]; } return newArr; } /** * 替换区间元素 * @param arr 目标数组 * @param start 开始下标-包含 * @param end 结束下标-排他 * @param key 需要替换的键 */ public static void fill(int[] arr,int start,int end,int key){ for (int i = start; i < end; i++) { arr[i] = key; } } /** * 替换全部元素 * @param arr 目标数组 * @param key 需要替换的键 */ public static void fill(int[] arr,int key){ fill(arr, 0, arr.length, key); } /** * 获取数组的字符串表示 * @param arr 目标数组 * @return 数组字符串 */ public static String toString(int[] arr){ String str = "["; for (int element : arr) { if(str.length() != 1){ str += ","; } str += element; } str += "]"; return str; } }
- 静态代码块
3.1 静态代码块、代码块、构造方法调用区别
静态代码块是类加载到方法区时才会被调用,该代码块只能初始化静态变量
代码块是创建对象时优先于构造方法调用,该代码块可以初始化成员变量和静态变量
构造方法是创建对象时调用,该方法可以初始化成员变量和静态变量
3.2 成员变量 vs 静态变量
成员变量:属于对象的变量,每个对象独享一份
静态变量:属于类的变量,每个对象都共享一份
3.3 经验:
初始化成员属性一般在构造方法中进行
初始化静态属性一般在静态代码块中进行package com.qf.test07; public class A { //成员属性 String str1; //静态属性 static String str2; //静态代码块:类加载到方法区时调用,可以初始化静态属性 static{ str2 = "ccc";//A.str2 = "bbb"; System.out.println("A类的静态代码块:" + str2); } //代码块:创建对象时优先于构造方法调用,可以初始化成员属性和静态属性 { str1 = "bbb";//this.str1 = "bbb"; str2 = "bbb";//A.str2 = "bbb"; System.out.println("A类的代码块:" + str1 + " -- " + str2); } //构造方法:创建对象时调用,可以初始化成员属性和静态属性 public A() { str1 = "aaa";//this.str1 = "aaa"; str2 = "aaa";//A.str2 = "aaa"; System.out.println("A类的构造方法:" + str1 + " -- " + str2); } }
package com.qf.test07; public class Test01 { /** * 知识点:静态代码块 * * 经验: * 初始化成员属性一般在构造方法中进行 * 初始化静态属性一般在静态代码块中进行 * */ public static void main(String[] args) { A a1 = new A(); A a2 = new A(); } }