static关键字
第一部分:
1、背景:
1.1、在一个类中可能包括有多个对象,但是这些对象在堆内存中分别开辟了新的空间,这些对象的name是不同的,但是这些对象的国籍是相同的,都是"cn";也就是说多个对象中存在多个数据,如果在一个类中有多个对象的话,数据的值是一样的,没有必要每一个都具备一个,这样会比较浪费空间;1.2、如果把country单独放在一个区域中,让这些对象来访问共享数据;这时如果对象需要访问共享数据的话,那么就来取需要的数据;这时就出现了一个关键字:static;2、static的用法:
2.1、static是一个修饰符,用于修饰成员,成员包括成员变量和成员函数;2.2、就多了一个调用方式,除了可以被对象调用外,还可以直接被类名锁调用,书写格式为:类名.静态成员;3、static的特点:
3.1、被static修饰的内容被对象所共享;3.2、随着类的加载而加载,并且随着类的消失而消失;
|--意思说就是随着Person类的加载进内存后,那么country="cn"这个值就已经在内存中开辟好了空间;
|--这个说明了静态的生命周期最长;
3.3、优先于对象存在;
|--静态成员在类中的时候,还没有对象,如果想要使用静态成员变量,只能使用类名使用;
3.4、可以直接类名所调用;4、实例变量和类变量的区别:
4.1、存放位置:
|--类变量随着类的加载而存在与方法区中;|--实例变量随着对象的建立而存在与对内存中;4.2、生命周期:
|--类变量生命周期最长,随着类的消失而消失;
|--实例变量生命周期随着对象的消失而消失;
5、静态数据在内存中的形式:
![]()
6、静态的使用事项:
6.1、静态方法只能访问静态成员,成员包括成员方法和成员变量;
|--非静态方法既可以访问静态也可以访问非静态;
6.2、静态方法中不可以定义this,super关键字;
6.3、主函数是静态的;|--因为静态优先于对象存在,所以静态方法中不可以出现this,也就是说静态不可以访问非静态;
7、静态有利有弊:
7.1、利处:
|--对对象的共享数据进行单独空间的存储,节省空间,没有必要每一个对象中都存储一份;
|--可以直接被类名锁调用;
7.2、弊端:
|--生命周期过长;
|--访问出现局限性;(静态虽好,但是只能访问静态)
8、什么时候使用静态
8.1、要从两个方面下手:因为静态修饰的内容有成员变量和成员函数;
|--什么时候定义静态变量(类变量)?
|--当对象中的出现共享数据时,该数据被静态所修饰,对象中的特有数据要定义成非静态,存在于堆内存中;
|--什么时候定义静态函数?
|--当功能内部没有访问到非静态数据(对象的特有数据),那么该功能就定义成非静态的;
9、静态的代码体现
class Person { // 特有的数据,特有内容随着对象存储 String name;//成员变量,实例变量 // 被static修饰的内容被对象所共享; static String country = "CN";//静态的成员变量,类变量 public void show(String name,String country) { this.name = name; this.country = country; System.out.println("name="+name+",,country="+country); } } class StaticDemo { public static void main(String[] args) { Person p = new Person(); p.show("zhangsan","CN"); // 当成员内静态修饰后,可以直接被类名锁调用 System.out.println(Person.country); } }
10、静态的应用
10.1、应用:多个应用程序中,具备了相同的功能,想要把这个相同的功能单独抽离出来,于是就把要操作数组的常见的功能单独封装到一个类中,这个类想什么时候用,就什么时候用,说白了,就是把这个功能封装在一个类中,找到了对象就找到了功能;10.2、软件说明书:/* 工具类:通常情况下工具类里面定义的都是静态方法。 */ /** 这是一个可以对数组进行操作的工具类,该类中提供了,获取最值,排序和打印数组等功能。 @author 范亚龙 @version v1.1 */ public class ArrayTool { /** 空参数构造函数。 */ private ArrayTool(){}//直接将构造函数私有化。不好创建对象。 /** 获取一个整形数组中的最大值。 @para arr 接收一个int类型的数组。 @return 会返回一个该数组中的最大值。 */ public static int getMax(int[] arr) { int max =0; for(int x=0;x<arr.length;x++) { if(arr[x]>arr[max]) max = x; } return arr[max]; } /** 获取一个整形数组中的最小值。 @para arr 接收一个int类型的数组。 @return 会返回一个该数组中的最小值。 */ public static int getMin(int[] arr) { int min =0; for(int x=0;x<arr.length;x++) { if(arr[x]<arr[min]) min = x; } return arr[min]; } /** 给int数组进行选择排序。 @para arr 接收一个int类型的数组。 */ public static void selectSort(int[] arr) { for (int x=0; x<arr.length-1; x++) { for (int y=x+1; y<arr.length; y++)//循环的嵌套,这个是尖朝下,因此要改变初始化条件。 { if(arr[y]<arr[x]) { int temp = arr[x]; arr[x] = arr[y]; arr[y] = temp; } } } } /** 给int数组进行冒泡排序。 @para arr 接收一个int类型的数组。 */ public static void bubbleSort(int[] arr) { for (int x=0; x<arr.length-1; x++) { for (int y=0; y<arr.length-x-1; y++) { if(arr[y+1]<arr[y]) { int temp = arr[y+1]; arr[y+1] = arr[y]; arr[y] = temp; } } } } /** 用于打印数组中的元素。打印形式是:[element1,element2,....] */ public static void printArray(int[] arr) { System.out.print("["); for(int x=0;x<arr.length;x++) { if(x!=arr.length-1) System.out.print(arr[x]+","); else System.out.println(arr[x]+"]"); } } } /* class ArrayTool { public static void main(String[] args) { int[] arr ={456,3,5,56,2,1}; int max = getMax(arr); System.out.println("max="+max); } public static int getMax(int[] arr) { int max =0; for(int x=0;x<arr.length;x++) { if(arr[x]>arr[max]) max = x; } return arr[max]; } } */
11、我的总结:
11.1、在一个类中要会区分哪些是对象的特有的数据,哪些是对象的共享数据;11.2、静态的生命周期最长;确认数据是否被多个对象所共享;11.3、静态是先存在的,对象是后存在的;11.4、非静态是什么都可以访问,而静态只能访问静态;11.5、主要静态在什么时候应该使用;