------- android培训、java培训、期待与您交流! ----------
主要内容:静态、主函数、制作帮助文档、静态代码块、对象的初始化过程、调用过程、单例设计模式(饿汉式、懒汉式)
一、static(静态)关键字
1,static关键字:用于修饰成员(成员变量和成员函数)
2,被修饰后的成员具备以下特点:
随着类的加载而加载:也就是,静态会随着类的消失而消失。说明静态的生命周期最长。
例:
String name;//非静态的成员变量,也叫实例变量
static String country = "CN";//静态的成员变量,也叫类变量。
实例变量和类变量的区别:
a.存在位置。
类变量随着类的加载而存在于方法区中
实例变量随着对象的建立而存在于堆内存中。
b.生命周期
类变量生命周期最长,随着类的消失而消失。
实例变量生命周期随着对象的消失而消失。
优先于对象存在
被对象所共享
可以直接被类名调用。类名.静态成员
3,静态的使用注意事项:
a.静态方法只能访问静态成员。
非静态方法既可以访问静态也可以访问非静态。
b.静态方法中不可以写this、super关键字。
因为静态优先于对象存在。所以静态方法中不可以出现this、super。
c.主函数是静态的
4,静态有利有弊
利处:对象的共享数据进行单独空间的存储,节省空间。没有必要每一个对象中都存储一份。
可以直接被类名调用。
弊端:生命周期过长。
访问出现局限性。(静态虽好,只能访问静态。)
5,什么时候使用静态?(必要掌握)
要从两方面下手:
因为静态修饰的内容有成员变量和函数。
(1)什么时候定义静态变量(类变量)呢?
当对象中出现共享数据时,该数据被静态所修饰。
对象中的特有数据要定义成非静态存在于堆内存中。
(2)什么时候定义静态函数呢?
当功能内部没有访问到非静态数据(对象的特有数据)
那么该功能可以定义成静态的。
6、静态的应用
每一个应用程序中都有共性的功能,可以将这些功能进行抽取,独立封装。
以便复用。
二、主函数
public static void main(String[] args)
主函数:是一个特殊的函数。作为程序的入口,可以被jvm调用。
主函数的定义:
public:代表着该函数的访问权限是最大的。
static:代表主函数随着类的加载就已经存在了。
void: 主函数没有具体的返回值。
main: 不是关键字,但是是一个特殊的单词,可以被jvm所识别。
(String[] arr):函数的参数,参数类型是一个数组,该数组中元素是字符串。字符串类型的数值。
args:arguments 参数的意思。
主函数是固定格式的:jvm识别。
jvm在调用主函数时,传入的是 new String[0];
三、帮助文档的制作 javadoc
1.使用方法:命令行输入:javadoc -d 文件夹名称 -author -version 文件名.java
-d:代表存储目录的意思;-author:代表提取文档作者; -version:代表提取文档版本。
2.注意:
a.一个类要想生成帮助文档,这个必须是public修饰。
b.一个类中默认会有一个空参数的构造函数,
这个默认的构造函数的权限和所属类一致。
如果类被public修饰,那么默认的构造函数也带public修饰符。
如果类没有被public修饰,那么默认的构造函数,也没有public修饰。
默认构造函数的权限是随着类的变化而变化的。
四、静态代码块
1.格式:
static{静态代码块中的执行语句}
2.特点:随着类的加载而执行,只执行一次,并优先于主函数执行。
3.作用:用于给类进行初始化的。
4.类有没有加载,可以用静态代码块来验证。
例:静态代码块、构造代码块、构造函数的执行顺序
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");
}
}
class StaticCodeDemo
{
public static void main(String[] args)
{
new StaticCode(3);
}
}
执行结构是(不写换行了):a c9 d
说明:静态代码块 优先于 构造代码块 优先于构造函数
并且说明静态代码块不能访问num,构造代码块可以访问num。
五、对象的初始化过程。
Person p = new Person("zhangsan",20);
该句话都做了什么事情?
1,因为new用到了Person.class。所以会先找到Person.class文件并加载到内存中。
2,执行该类中的static代码块,如果有的话,给Person.class类进行初始化。
3,在堆内存中开辟空间,分配内存地址。
4,在堆内存中建立对象的特有属性,并进行默认初始化。
5,对属性进行显示初始化。
6,对对象进行构造代码块初始化。
7,对对象进行对应的构造函数初始化。
8,将内存地址赋给栈内存中的p变量
六、对象调用成员过程
七、单例设计模式
1,设计模式:解决某类问题最行之有效的方法。
java中有23种设计模式。
2,单例设计模式:解决一个类在内存只存在一个对象。
思想:想要保住对象唯一。
<1>.为了避免其他程序过多建立该类对象,先禁止其他程序建立该类对象。
<2>.还为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象。
<3>.为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。
这三步怎么用代码体现呢?
<1>.将构造函数私有化。
<2>.在本类中创建一个本类对象。
<3>.提供一个方法可以获取到该对象。
注意:对于事物该怎么描述,还怎么描述。
当需要将该事物的对象保证在内存中唯一时,就将以上三步加上即可。
(一)这个是先初始化对象。称为:饿汉式
饿汉式代码如下:
class Single
{
private Single(){} //禁止其他程序创建本类对象,将构造函数私有化。
private static Single s = new Single();//静态方法访问静态成员,所以static修饰
public static Single getInstance() //静态修饰,供其他程序类名调用。
{
return s;
}
}
class SingleDemo
{
public static void main(String[] args)
{
Single ss = Single.getInstance();
}
}
其他程序只能通过getInstance()方法来操作本类对象了。
方法被调用只有两种方式可以进行:1,建立对象 2,类名调用。
构造函数已被私有了,不可能建立对象了。
方法只能用被类名调用,能用类名调用,这个方法就要static标识。
同时静态方法在访问类中的成员s,所以成员 s 也要被static。
s同时是类中的变量,所以通常要private。
特点: 这种单例设计模式称为懒汉式。在调用getInstance()方法时,
这唯一对象的就创建好了,直接拿到使用。这种思想是空间换时间
对象早早的建立好存放在那,只有来拿就好了。
(二)对象是方法被调用时,才初始化,也叫做对象的延时加载。称为:懒汉式
懒汉式代码:
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;
}
}
特点:这种单例设计模式的特点是当通过对外提供的取得单例的方式获取对象时,
先判断对象时候存在,如果不存在,那么就创建一个,否则直接使用已经存在的对象。
但是,if(s == null )这句话容易出现并发操作,如果两个线程同时来取对象,
判断条件为null,那么就会创建多个对象,所以当判断条件后,再使用一个同步代码块
来实现线程的同步,再在里面使用if判断,来判断对象是否存在。这种使用双重if判断
以及使用同步关键synchronized的方式可以稍微提高一下效率。
这种单例模式设计的思想是:时间换空间。当通过getInstance()来获取对象时,
才创建实例,这样可以节省空间,但是效率略低。
记录原则:定义单例建议使用饿汉式。