静态
static(静态)关键字
- static关键字:
用于修饰成员:成员变量和成员函数(只能修饰成员不能修饰局部); - 被修饰后的成员具备以下特点:
- 随着类的加载而加载,随着类的消失而消失,生命周期最长;
- 优先于对象存在,静态先存在,对象后存在;
- 被所有对象所共享(静态成员在类中只有一份);
- 可以直接被类名调用(不创建对象也可以使用):类名.静态成员;
- 使用注意:
- 静态方法只能访问静态成员(包含方法和成员);非静态即可以访问静态也可以访问非静态;
- 静态方法中不可以写this、super关键字(无对象可指);
- 主函数是静态的;
- 静态的利与弊:
- 利:对对象的共享数据进行单独空间存储,节省空间,没必要每个对象都存储,可直接被类名调用;
- 弊:生命周期过长,访问出现局限性,只能访问静态;
- 静态什么时候使用?
- 什么时候定义静态变量(类变量)呢?
当对象中出现共享数据时,该数据被静态所修饰。对象中的特有数据要定义成非静态存在于堆内存中。 - 什么时候定义静态函数呢?
当功能内部没有访问到非静态数据(对象的特有数据),那么该功能可以定义成静态的。
- 什么时候定义静态变量(类变量)呢?
- 静态的应用:
每一个应用程序中都有共性的功能,可以将这些功能进行抽取,独立封装,以便复用(工具类)。为方便于使用,可以将方法都静态,但是该类还是可以被其他程序建立对象的。为了更为严谨,强制让该类不能建立对象。可以通过将构造函数私有化完成。
class Person
{
String name;//成员变量,实例变量。
static String country = "CN";//静态的成员变量,类变量。
public static void show()
{
System.out.println("::::");
this.haha();
}
public void haha()
{}
}
class StaticDemo
{
public static void main(String[] args)
{
Person p = new Person();
//p.name = "zhangsan";
//p.show();
//System.out.println(p.country);
//System.out.println(Person.country);
Person.show();
}
}
静态代码块:
- 格式:
static
{
静态代码块中的执行语句;
} - 特点:随着类的加载而执行,只执行一次(新建多个对象的时候也只执行一次,与新建对象无关),一般用于给类进行初始化;
注意:
- 一个类中可建多个静态代码块,都随类而加载;
- 当新建类对象被值为null时不加载静态代码块;
例:StaticCode s=null;
此时不加载静态代码块,因为此时只是引用,无内容加载,只有引用到类中的内容时,才会加载;例:new StaticCode();此语句就引用了类中的默认构造函数:StaticCode(){};
class StaticCode
{
int num = 9;
StaticCode()
{
System.out.println("b");
}
static
{
System.out.println("a");
}
{
System.out.println("c"+this.num);
}
StaticCode(int x)
{
System.out.println("d");
}
public static void show()
{
System.out.println("show run");
}
}
class StaticCodeDemo
{
static
{
//System.out.println("b");
}
public static void main(String[] args)
{
new StaticCode(4);//a c d
//new StaticCode();
//new StaticCode();
//System.out.println("over");
//StaticCode.show();
//StaticCode s = null;
//s = new StaticCode();
//StaticCode.show();
}
static
{
///System.out.println("c");
}
}
对象调用成员过程(总结):
Person p=new Person(“zhangsan”,20);
该语句在执行时在内存中的操作步骤如下:
1. new用到了Person.class所以会先加载Person.class文件;
2. 执行该类中的static代码块(如有),给Person.class类进行初始化;
3. 在堆内存中开辟空间,分配内存地址;
4. 在堆内存中建立对象的特有属性,并进行默认初始化;
5. 对属性进行显示初始化;
6. 对对象进行构造代码块初始化;
7. 对对象进行对应的构造函数初始化;
8. 将内存地址赋值给栈内存中的p变量;
main()函数
public static void main(String[] args)
主函数:是一个特殊的函数,作为程序才入口,可以被jvm调用;
1. 主函数的定义:
- public:代表着该函数访问权限是最大的;
- static:代表主函数随着类的加载就已经存在了;
- void:主函数没有具体的返回值;
- main:不是关键字,但是是一个特殊的单词,可以被jvm识别;
- (String[] args):函数的参数,参数的类型是一个数组,该数组的元素是字符串,字符串类型的数组;
2. 特征:
- 主函数是固定格式的,被jvm识别,出了变量名args可以被自定义,其他都不能修改;
- jvm在调用主函数时,传入的是new String[0];
3. 其他:
- 主函数也是函数时可以相互调用的(在不同类中);
- 在同一类中也可以有多个main主函数(以重载的形式出现);
- 主函数的参数可以在被调用时传入值(字符串数组);
4. 附加知识点:
当接收来自其他地方飞class文件且存放的位置与调用文件不在同一目录时,可使用classpath命令设置环境变量;用法:set classpath=.文件路径(”.”为当前目录);
帮助文档(API文档)
- 使用来自其他地方的class文件需要程序说明书,Java说明书通过文档注释来完成,格式:
/**
通常是类的描述信息;
*/ - 当注释文档建立完成后需要用javadoc.exe工具对文档进行提取生成文档,在dos环境中使用该命令是需要对提取文档指定存放位置,语法形式为:
javadoc -d myhelp -author -version ArrayTool.java
author:提取作者;
version:提取版本; - 注意:
- 需要生成帮助文档的类必须用public修饰,否则无法读取;
- 标识符的书写:@param arr 文字功能描述:
@param:标识符的格式
arr:函数内形式参数变量名,变量名与文字功能描述之间有个空格不能省略,否则会报错; - 类中不被public修饰的函数将不被提取;
- 默认构造函数的权限是随着类的变化而变化的,与类的修饰权限一致;
单例设计模式:
设计模式:解决某一类问题最行之有效的方法,Java中23中设计模式:
单例设计模式:解决一个类在内存中只存在一个对象;
- 饿汉式(先初始化对象):
class Single
{
private static final Single s = new Single();//自建一个本类对象;
private Single(){}//私有化构造函数,使其在其他类中不能创建对象;
public static Single getInstance() //提供一个获取该对象的方法;
{
return s;
}
}
- 懒汉式(对象的延时加载,方法被调用时才初始化)
class Single
{
private static Single s = null;//先声明一个该类的变量;
private Single(){}//私有化构造函数,使其在其他类中不能创建对象;
public static Single getInstance()//定义一个获取该类对象的方法;
{
if(s==null)//双重判断提高效率;
{
synchronized(Single.class)//使用同步保证线程安全
{
if(s==null)
s = new Single();
}
}
return s;
}
}