/*static关键字*/
作用1:将公用的数据static修饰,减少内存的占用,例如:当所有人的国籍都是"CN"时,如果每一个人都标识 String country="CN",
就会占用大量的内存空间,为了防止这种情况,用static修饰 static String country="CN";则变为全局恒定变量(是为一特定区间:方法区,共享区,数据区)。
(简单的说:就是没用static修饰也是可以的,只是会占用内存空间)
(static修饰的不仅是成员变量,也可以修饰成员函数,修饰成员变量表示开辟一个独立空间,将数据保存在里面,而不会重复在堆内存出现占用不必要的内存)
作用2:成员数据被static修饰之后多了一个调用函数的方式,例如:static String country="CN";类名为Person,那么直接有
System.out.println(Person.countrry)这种直接以类名不需要建立对象的表达方式。
static 的特点:
1.随着类的加载而加载,随着类的消失而消失
//说明静态成员变量(也叫类变量)的生命周期最长,这也是不能将所有成员变为静态的原因,会持续的占用内存,当然最重要的原因是不是每一个成员变量都是共享的
2.优先于对象存在
//因为是在方法区内,与对象是否存在无关,侧面反映可以被类名直接调用
3.被所有对象所调用
//在方法区内直接可被调用
4.可以被类名直接调用
注意事项:1.静态方法只能访问静态成员。例如:class Person{}类中,String name; Person.name是在用静态方法调用非静态变量是编译错误的。
2.静态方法中不能定义this,super关键字,因为静态成员变量优先于对象存在。
/*main()函数(主函数)*/
public static void main(String[] args) //主函数是静态的
主函数是一个特殊的函数,他是程序的起始点,可以被jvm调用
public:代表该函数的访问权限是最大;
static:代表主函数随着类的加载而加载,存在于方法区,与是否建立对象无关
void:表示主函数没有具体的返回值
main:不是关键字,但是是一个特殊的单词可以被jvm识别
(String[] arr):函数的参数,参数类型是数组,数组中的元素是字符串
主函数是固定格式:能被jvm识别。
/*什么时候使用静态*/
static 用来修饰静态成员变量和静态函数
1.修饰静态成员变量,该变量含有共有的数据,存储于方法区中,
2.修饰静态函数的时机:当功能内部没有访问到非静态数据(对象的特有数据)时,那么该功能可以定义成静态的
例如:
class Person
{
String name;
public static void run()
{
System.out.println("阿秋是天才"+name); //当功能内部没有访问到对象的特有数据时,可以将其定义为静态
}
/*//这句话理解有2点:
1.定义该功能静态也行不定义也行,关键点在于在没有访问对象特有数据时,如果每一个对象都要打印与特有数据无关的语句的话,会重复占用内存
既然与对象特有数据无关,那么直接static用类直接调用,省着再创建对象然后用对象调用;
2.根据static的特性:静态方法只能访问静态成员,如果打印语句变为 System.out.println("阿秋是天才"+name),编译会失败,因为静态方法只能访问静态成员,name不是。
*/
}
class Q1
{
public static void main(String[] args)
{
Person p=new Person();
p.run();
}
}
/*静态的应用*/
构造函数的私有化:private Person(){} //构造函数初始化使其他外部类不能new出对象,只能在本类中建立对象
//创建对象,需要构造函数对其进行初始化。将构造函数私有化后,其他类创建该对象时,由于不能访问被私有化的构造函数,就不能对对象进行初始化,也就不能创建对象了。
//而在本类中,可以使用被私有的成员,所以可以对创建对象进行初始化,也就可以创建对象。
/*帮助文档的制作*/
/*静态代码块*/
静态代码块的格式:
static
{
//执行语句
}
//静态代码块的特点:随着类的加载而执行,只能执行一次(很重要)
例如:
class Person
{
static
{
System.out.println("a");
}
}
class Q1
{
static
{
System.out.println("b");
}
public static void main(String[] args)
{
new Person();
new Person();
}
static
{
System.out.println("d");
}
}
//打印结果为:b,d,a 首先静态代码块优先于构造代码块执行,构造代码块优先于程序(包括主函数)执行。
//因此先打印Q1类中的b,c,最后打印程序中的a,又根据静态代码块只能执行一次的特点,所以只能打印一个a
/*静态代码块,构造代码块,构造函数,重载,函数*/
class Person
{
Person()
{
System.out.println("a"); //构造函数
}
Person(int x)
{
System.out.println("b");
}
static
{
System.out.println("c"); //static修饰的是静态代码块
}
{
System.out.println("d"); //构造代码块
}
public static void run()
{
System.out.println("e"); //一般函数
}
}
class Q1
{
public static void main(String[] args)
{
new Person().run();
}
}
//打印结果为:c,d,a,e
//总结:静态代码块>(默认初始化值)>构造代码块>构造函数>成员函数
/*静态代码块,构造代码块,构造函数的先后顺序*/
静态代码块>构造代码块>构造函数>成员函数
静态代码块:用于类的初始化
构造代码块:用于对象的初始化
构造函数 :给对应对象初始化的
/*方法区的定义*/
方法区习惯的认为是static修饰的共享的成员变量储存的地方,其实方法区还是函数方法储存的地方
例如:
public vod run(){}这种类似的方法在方法区中保留。
/*单例设计模式*/
书籍《设计模式》
设计模式:解决一类问题最行之有效的方法
java中总共有23种设计模式
单例设计模式:实现一个类中只有一个对象。
例如:
class Person
{
private Person(){} //第一步:私有化构造函数,因为在其他类能创建对象的原因是:构造函数未私有
private static Person p=new Person(); //第二步:在本类中建立对象,因为第三步是静态方法调用,所以Person类的p必须是静态
public static Person getInstance() //第三步:在本类中建立外界获取途径,用类名直接调用方式获取。
{
return p;
}
}
class Q1
{
public static void main(String[] args)
{
Person p1=Person.getInstance();
}
}
/*懒汉式和饿汉式的初步了解*/
/*饿汉式*/
class Person
{
private Person(){}
private static Person p=new Person();
public static Person getInstance()
{
return p;
}
}
/*懒汉式*/
class Person
{
private Person(){}
private static Person p=null;
public static Person getInstance()
{
if(p==null)
{
synchronized(Person.class) //确定其安全性
{
if(p==null)
p=new Person();
}
}
return p;
}
}
//懒汉式和饿汉式的区别:1.定义单例(指实现一个类只设计出一个对象的功能),建议使用饿汉式(吐槽:我就不知道懒汉式有何卵用)
// 2.饿汉式是指Person类一进内存就建立对象,果然很饿;而懒汉式是指Person类进入内存,很淡定不慌,等到调用getInstance()
// 方法了才建立对象,特别懒,而且这种安全性差,到底有何用?
|
|