一、静态(static)
1、static:是一个修饰符,用于修饰成员(成员变量、成员函数)。
代码示例:
class Person
{
String name; //成员变量,实例变量。
static String country = "cn"; //静态的成员变量,类变量。
public static void show() //成员函数
{
System.out.println(name+"......"+country);
}
}
2、当成员被静态修饰后,就多了一种调用方式。除了可以被对象调用外,还可以直接被类名调用。
静态的两种调用方式:
a.类名.静态成员 //例:Person.country
b.对象名.静态成员 //例:new Person().show()
3、什么时候使用静态?
要从两方面下手:因为静态修饰的内容有成员变量和成员函数。
什么时候定义静态的变量(类变量)呢?
当对象中出现共享数据时,该数据被静态所修饰。对象中的特有数据要定义成非静态存在于堆内存中。
什么时候定义静态函数呢?
当功能内部没有访问到非静态数据(对象的特有数据),那么该功能可以定义成静态的。
4、被static修饰的成员存放在内存的方法区(或者称为共享区、数据区)当中,其它对象则存放在堆内存中。
5、static的特点:
①.随着类的加载而加载,随着类的消失而消失。(说明它的生命周期最长)
当类一加载进内存,静态成员就已经在内存的方法区中开辟好了空间而在内存中存在了。
②.优先于对象存在。
③.被所有对象所共享。
④.可以直接被类名所调用。
6、实例变量和类变量的区别:
①、存放位置。
类变量随着类的加载而存在于方法区中。
实例变量随着对象的建立而存在于堆内存中。
②、生命周期。
类变量生命周期最长,随着类的消失而消失。
实例变量生命周期随着对象的消失而消失。
7、静态使用注意事项:
①、静态方法只能访问静态成员。
非静态方法既可以访问静态也可以访问非静态。
②、静态方法中不可以定义this、super关键字。
因为静态优先于对象存在。所以静态方法中不可以出现this。
③、主函数(main)是静态的。
8、静态的利弊
利处:①.对对象的共享数据进行单独空间的存储,节省内存空间。没有必要每个对象中都存储一份。
②.可以直接被类名调用。
弊端:①.生命周期过长。
②.访问出现局限性。(静态虽好,但只能访问静态)
二、主函数(main)
1、主函数:是一个特殊的函数。作为程序的入口,可以被JVM调用。
2、主函数固定格式:publicstatic void main(String[] args){}
- public:代表着该函数的访问权限是最大的。
- static:代表着主函数随着类的加载就已经存在了。
- void:主函数没有具体的返回值。
- main:不是关键字,但是它是一个特殊的单词,可以被JVM识别。
- (String[]arr):函数的参数,参数类型是一个数组,该数组中的元素是字符串。字符串类型的数组。
注:主函数固定格式被JVM识别,就算主函数出现重载情况,JVM也只是识别主函数的固定格式。
3、其它事项:
①.JVM在调用主函数时,传入的是new String[0];,即长度为0的字符串数组对象。当打印输出args[0]的时候就会出现角标越界的报错。
②.在运行java程序的时候可以通过手动的动态传入主函数参数的方式来实现某些目标,
格式:java类名参数1参数2参数3...
示例:
class MainDemo
{
public static void main(String[] args)
{
for(int x=0; x<args.length; x++)
System.out.println(args[x]);
}
}
结果:
三、静态的应用
1、工具类:每一个应用程序中都有共性的功能,可以将这些功能进行抽取,独立封装,以便复用。这些抽取出来的功能组成的类就称为工具类。
2、工具类的好处:
①.可以避免代码臃肿,减少相同代码的重复编写,提高代码的复用性和阅读性。
②.可以通过类名灵活的调用所需要的功能,使程序更为严谨。
注:虽然可以通过建立工具类的对象来使用工具方法,但是由于对象是用于封装数据的,但是工具类中并未封装特有数据,所以需要将工具类中的工具方法都静态。
3、将方法都静态后,可以方便于使用,但是这样的工具类还是可以被其它程序建立对象。为了更为严谨,强制让该类不能建立对象,可以通过将构造函数私有化达到目的。
代码示例:
class ArrayTool
{
privateArrayTool(){} //将构造函数私有化,强制让该类不能建立对象。
public static int getMax(int[] arr){
int max = 0;
for(int x=1; x<arr.length; x++)
if(arr[x]>arr[max])
max = x;
return arr[max];
}
}
(建议)总结:
①、工具类中的工具方法全部静态。
②、工具类中的构造方法要被私有化,防止被建立对象。
③、工具类中不需要暴露出去的内容也需要被私有化封装起来。
四、小知识点:制作帮助文档
1、帮助文档:便于程序开发人员了解工具类中的功能方法的详细内容和相关介绍。
2、Java制作方式:使用(JDK目录的bin目录下)javadoc.exe 这个工具,以及文档注释来完成。
3、制作步骤:
①.在工具类的每个方法头上通过文档注释,配合@符号和一些固定字符来对方法中的关键部分做一定的标识。
还可以指定该帮助文档的作者、版本...等信息。
示例:
/**
获取一个整型数组中的最大值。
@param arr 接收一个int类型的数组。
@return 会返回一个该数组中的最大值。
*/
public static int getMax(int[] arr)
{
int max = 0;
for(int x=1; x<arr.length; x++)
if(arr[x]>arr[max])
max = x;
return arr[max];
}
②.再通过javadoc这个命令和一些参数来生成一个Java帮助文档。命令格式是:
javadoc -d文档生成目录 [-参数1 -参数2 ...]工具类源文件名
示例:javadoc -d myhelp -author -version ArrayTool.java
myhelp:存放帮助文档生成的目录,这里代表当前源文件所在目录。前面用-d表示这是一个目录。
-author:作者
-version:当前文档版本
ArrayTool.java:工具类的源文件名
4、注意事项:
①、工具类的类名必须要被public所修饰,否则生成帮助文档的时候就会报错。
②、如果想将工具类中的某个方法暴露出去,只要将该方法的权限设置为public就可以了。
五、静态代码块
1、什么是静态代码块?
用static关键字声明的代码块。
2、格式:
static
{
//静态代码块中的执行语句。
}
3、特点:
①、随着类的加载而执行,只执行一次。
②、优先于主函数、构造代码块先执行。
4、作用:用于给类进行初始化。(即当类一加载进内存就需要被执行的动作,这些随着类的加载而执行的动作可以放在静态代码块中来给类进行初始化)
代码示例:
class Demo
{
static
{
System.out.println("1、静态代码块");
}
{
System.out.println("2、构造代码块");
}
Demo()
{
System.out.println("3、构造方法");
}
}
class StaticCodeDemo2
{
static //主方法所在类的静态代码块。
{
System.out.println("0、静态代码块,优先于主方法执行");
}
public static void main(String[] args)
{
newDemo(); //新建一个Demo类的匿名对象。
System.out.println("4、主方法");
}
}
结果:
六、对象的初始化过程
代码示例:
class Person{
private String name;
private int age;
private static String country = "cn";
Person(String name,int age){
this.name = name;
this.age = age;
}
public void setName(String name){
this.name = name;
}
{
System.out.println("构造代码块..."+name+"..."+age);
}
}
class PersonDemo{
public static void main(String[] args){
Person p = new Person("zhangsan",20);
}
}
对象初始化过程:Person p = newPerson("zhangsan",20); 这句话都做了什么事情?
1、因为new用到了Person.class,所以会先找到Person.class文件并加载到内存中。
2、执行该类中的static代码块,如果有的话,给Person.class类进行初始化。
3、在堆内存中开辟空间,分配内存地址。
4、在堆内存中建立对象的特有属性,并进行默认初始化。
5、对属性进行显示初始化。
6、对对象进行构造代码块初始化。
7、对对象进行与之对应的构造函数初始化。
8、将内存地址赋给栈内存中的p变量。