Java学习6:static关键字
来源:互联网 发布:日语软件测试工程师 编辑:程序博客网 时间:2024/06/05 05:11
特点
- 是一个修饰符,用于修饰成员(成员变量和成员函数);
- 被所有对象所共享;
- 随着类的加载而加载,随着类的消失而消失,生命周期最长;
- 优先于对象存在:静态是先存在,对象是后存在;
- 当成员被静态修饰后,就多了一个调用方式,除了可以被对象调用外,还可以直接被类名调用:类名.静态成员。
public class Demo{ public static void main(String[] args) { Person p1 = new Person("zhangsan"); Person p2 = new Person("lisi"); p1.show(); System.out.println(Person.country);//静态成员直接被类名调用 }}class Person{ String name;//成员变量,实例变量 static String country = "CN";//静态的成员变量,类变量 Person(String name){ this.name = name; } void show(){ System.out.println(name + ":" + country); }}
见下图,country前面加static,则会被放置于共享区;如果country前面不加static,则会在每个对象中存在country=“CN”:
实例变量和类变量的区别
存放位置
类变量随着类的加载而存在于方法区中;
实例变量随着对象的建立而存在于堆内存中。
生命周期
类变量生命周期最长, 随着类的消失而消失;
实例变量生命周期随着对象的消失而消失。
静态使用注意事项
1.静态方法只能访问静态成员,非静态方法既可以访问静态,也可以访问非静态;
2. 静态方法中不可以定义this、super关键字,因为静态优先于对象存在;
3. 主函数是静态的。
静态有利有弊
利处:对对象的共享数据进行单独空间的存储,节省空间,没有必要每一个对象中都存储一份、可以直接被类名调用;
弊端:生命周期过长、访问有局限性(只能访问静态)。
主函数的含义
public static void main(String[] arg)
public:代表该函数的访问权限是最大的;
static:代表主函数随着类的加载就已经存在了;
void:主函数没有具体的返回值;
main:不是关键字,但是是一个特殊的单词,可以被jvm识别;
String[] args:args(arguments),函数的参数,参数类型是一个数组,该数组中的元素是字符串。字符串类型的数组;
主函数是固定格式的,被jvm所识别,jvm在调用主函数时,传入的是new String[0]。
public class Demo{ public static void main(String[] args){ System.out.println(args);//输出 [Ljava.lang.String;@135fbaa4 System.out.println(args.length);//输出 0 }}
命令行中使用java命令启动虚拟机执行Demo类时,其会调用该类中的main函数,在后面可以传入字符串,见下图:
public class Demo{ public static void main(String[] args){ System.out.println(args[0]); System.out.println(args.length); }}
什么时候使用静态
何时定义静态变量(类变量)?
当对象中出现共享数据时,该数据被静态所修饰;对象中的特有数据定义为非静态,存在于堆内存中。
何时定义静态函数?
当功能内部没有访问到非静态数据(对象的特有数据),该功能可以定义为静态的。
//需要定义为静态函数public class Demo{ public static void main(String[] args){ Person.show();//不建立对象,直接使用类调用函数 }}class Person{ String name; //未使用非静态数据,定义为静态函数 //因为未使用静态数据,所以当只需要单独执行此函数时, //建立对象是多余的,需要不建立对象也可调用此函数,所以定义为静态函数 public static void show(){ System.out.println("Person"); }}
//不能定义为静态函数public class Demo{ public static void main(String[] args){ Person p1 = new Person(); p1.show(); }}class Person{ String name; //使用非静态数据,不能定义为静态函数 public void show(){ System.out.println("Person:" + name);//需要打印姓名(非静态数据) }}
静态的应用_ArrayTools类
每一个应用程序中都有共性的功能,可以将这些功能进行抽取,独立封装,以便复用。
Demo.java文件:
/* 虽然可以通过建立ArrayTools的对象使用这些方法对数组进行操作,但是: 1.对象适用于封装数据的,但是ArrayTools对象并未封装特有数据; 2.操作数组的每一个方法都没有用到ArrayTools对象中的特有数据。 此时,考虑到程序更严谨,是不需要对象的,可以将ArrayTools中的方法定义为static的,直接通过类名调用即可。 将方法都静态后,可以方便使用,但是该类还是可以被其他程序建立对象的,为了更加严谨,强制该类不能建立对象,可以将构造函数私有化:private ArrayTools(){}。*/public class Demo{ public static void main(String[] args){ int[] array = {44,41,43,45,46}; System.out.println("max = " + ArrayTools.getMax(array));//直接类名调用,不用生成对象 System.out.println("min = " + ArrayTools.getMin(array)); ArrayTools.printArray(array); ArrayTools.selectSort(array); ArrayTools.printArray(array); int index = ArrayTools.binarySearch(array, 40); System.out.println(index); /* ArrayTools tools = new ArrayTools(); int[] array = {44,41,43,45,46}; System.out.println("max = " + tools.getMax(array)); System.out.println("min = " + tools.getMin(array)); tools.printArray(array); tools.selectSort(array); tools.printArray(array); int index = tools.binarySearch(array, 40); System.out.println(index);*/ }}
ArrayTools.java文件:
/** * Created by hacker on 2017/9/22. */public class ArrayTools { private ArrayTools(){}//构造函数私有化 public static int getMax(int[] array){//求数组最大值 int max = 0; for(int i=1; i<array.length; i++){ if(array[i] > array[max]) max = i; } return array[max]; } public static int getMin(int[] array){//求数组最小值 int min = 0; for(int i=1; i<array.length; i++){ if(array[i] < array[min]) min = i; } return array[min]; } public static void printArray(int[] array){//输出数组 System.out.printf("["); for(int i=0; i<array.length; i++){ if(i != array.length - 1) System.out.print(array[i] + ", "); else System.out.println(array[i] + "]"); } } public static void selectSort(int[] array){//选择排序 for(int i=0; i<array.length-1; i++){//遍历数组 for(int j=i+1; j<array.length; j++) if(array[j] < array[i]) { int temp = array[i]; array[i] = array[j]; array[j] = temp; } } } public static void bubbleSort(int[] array){//冒泡排序 for (int i=0; i<array.length-1; i++) for(int j=0; j<array.length-1-i; i++){ if(array[j] > array[j+1]){ int temp = array[j]; array[j] = array[j+1]; array[j+1] = temp; } } } public static int binarySearch(int[] array, int num){//二分法/折半查找法 int min = 0; int max = array.length - 1; int mid = (min + max) / 2; while(min <= max) { if (array[mid] < num) { min = mid + 1; mid = (min + max) / 2; } else if (array[mid] > num) { max = mid - 1; mid = (min + max) / 2; } else return mid; } return -1; }}
帮助文档的制作_以ArrayTools类为例
需求
如果将ArrayTools.class文件发送给其他人,其他人只需要将该文件设置到classpath的路径下,就可以使用该工具类,但是对方不清楚该类中定义了多少方法,所以需要制作程序使用说明书,java的说明书通过文档注释来完成。
制作方法
注意:私有的方法不会被提取到帮助文档。
/** 对数组进行操作的工具类,提供了获取最大值、最小值、输出数组、选择排序、冒泡排序、折半查找法功能。 @author 高世皓 @version V1.0 */public class ArrayTools { /** 空参数构造函数,被私有化 */ private ArrayTools(){} /** 获取一个整形数组中的最大值 @param array 接收一个int类型的数组 @return 会返回一个该数组中的最大值 */ public static int getMax(int[] array){ int max = 0; for(int i=1; i<array.length; i++){ if(array[i] > array[max]) max = i; } return array[max]; } /** 获取一个整形数组中的最小值 @param array 接收一个int类型的数组 @return 会返回一个该数组中的最小值 */ public static int getMin(int[] array){ int min = 0; for(int i=1; i<array.length; i++){ if(array[i] < array[min]) min = i; } return array[min]; } /** 打印一个整形数组中的元素 @param array 接收一个int类型的数组 */ public static void printArray(int[] array){ System.out.printf("["); for(int i=0; i<array.length; i++){ if(i != array.length - 1) System.out.print(array[i] + ", "); else System.out.println(array[i] + "]"); } } /** 选择排序,对一个整形数组按照从小到大的顺序排序 @param array 接收一个int类型的数组 */ public static void selectSort(int[] array){ for(int i=0; i<array.length-1; i++){//遍历数组 for(int j=i+1; j<array.length; j++) if(array[j] < array[i]) { int temp = array[i]; array[i] = array[j]; array[j] = temp; } } } /** 冒泡排序,对一个整形数组按照从小到大的顺序排序 @param array 接收一个int类型的数组 */ public static void bubbleSort(int[] array){ for (int i=0; i<array.length-1; i++) for(int j=0; j<array.length-1-i; i++){ if(array[j] > array[j+1]){ int temp = array[j]; array[j] = array[j+1]; array[j+1] = temp; } } } /** 二分法/折半查找法,查找某个数值在整形数组中的位置,没有返回-1 @param array 接收一个int类型的数组 @param num 要查找的数值 @return 返回查找到的位置索引 */ public static int binarySearch(int[] array, int num){ int min = 0; int max = array.length - 1; int mid = (min + max) / 2; while(min <= max) { if (array[mid] < num) { min = mid + 1; mid = (min + max) / 2; } else if (array[mid] > num) { max = mid - 1; mid = (min + max) / 2; } else return mid; } return -1; }}
使用命令javadoc -d myHelpDoc ArrayTools.java -author -version生成说明书,注意myHelpDoc为文件夹的名称,如果该目录下没有该文件夹,则会自动生成一个。
帮助文档效果
打开其中的index.html即可:
静态代码块
格式
static{
静态代码块中的执行语句。
}
特点
随着类的加载而运行,只执行一次,并优先于主函数,用于给类进行初始化的。
eg1:
/* b c a end */class staticCode{ static{ System.out.println("a"); }}class Demo{ static{ System.out.println("b"); } public static void main(String[] args){ new staticCode(); new staticCode();//此时类已经加载了,不再执行静态代码块 System.out.println("end"); } static{ System.out.println("c"); }}
eg2:
/* a show code */class staticCode{ static{ System.out.println("a"); } public static void show(){ System.out.println("show code"); }}class Demo{ public static void main(String[] args){ staticCode.show(); }}
eg3:
/* 静态代码块 构造代码块, num = 2 构造函数2 */class staticCode{ int num = 2; {//给对象初始化 System.out.println("构造代码块" + ", num = " + num); } static{//给类初始化,不能访问num,因为num为非静态变量 System.out.println("静态代码块"); } staticCode(){ System.out.println("构造函数1"); } staticCode(int x){ System.out.println("构造函数2"); } public static void show(){ System.out.println("show code"); }}class Demo{ public static void main(String[] args){ new staticCode(4); }}
对象的初始化过程
public class Demo{ public static void main(String[] args){ Person p = new Person("liming", 23); p.show(); }}class Person{ private String name = "shgao"; private int age; private static String country = "CN"; {//给对象初始化 System.out.println("构造代码块"); } static {//给类初始化 System.out.println("静态代码块"); } Person(String name, int age){ this.name = name; this.age = age; System.out.println("构造函数初始化"); } void show(){ System.out.println("name: " + name + ", " + "age: " + age + ", country: " + country); }}
执行顺序
Person p = new Person("liming", 23);1.new用到了Person.class,会找到Person.class文件并加载到内存中;2.执行该类中的静态代码块和静态变量初始化,给类进行初始化,顺序由上至下;3.在堆内存中开辟空间,分配内存地址;4.在堆内存中建立对象的特有属性,并进行默认初始化(0 null);5.对对象进行显示初始化;5.对对象进行构造代码块初始化;6.对对象进行对应的构造函数初始化;7.将内存地址赋值给栈内存中的p变量。
- Java学习6:static关键字
- Java学习笔记----static关键字
- 个人学习-java-static关键字
- Java学习·Static关键字
- Java学习之static关键字
- 学习Java之关键字 static
- JAVA学习日志:static关键字
- Java学习之static关键字
- Java学习笔记--static关键字
- java学习 十一、关键字static
- java学习笔记 static,final关键字学习
- Java学习之关键字static的学习
- C++学习6:static关键字
- java基础知识6static关键字
- JAVA学习八:static(静态)关键字
- 7、从零开始学习JAVA--static关键字
- 黑马程序员--Java学习09--static关键字
- Java学习笔记(六)static关键字
- 2462: [BeiJing2011]矩阵模板
- make menuconfig出错,ncurses安装失败
- 内存溢出和内存泄漏的区别
- 9月20日云栖精选夜读:异构计算&高性能计算分论坛——揭秘拿什么实现超算平民化、国际化?
- springboot基础
- Java学习6:static关键字
- 用js将简体转换为繁体
- spring boots 持久化 报错
- 阿里云大学安全课程-阿里云首席安全研究员吴瀚清:WannaCry事件最“细思恐极“的一个事实是?
- 重绘Winform窗体
- POJ 3295.Tautology
- LeetCode 525. Contiguous Array
- 如何进行Cause GC且解决Heap updates are NOT ENABLED for this client
- @SuppressWarnings可以抑制的警告类型