//static(静态)关键字
作为一个修饰符存在。对变量进行修饰作用,起到特别含义。
用法:是一个修饰符,用于修饰成员中都有的共性的东西(成员变量和成员函数),不能用来修饰局部。起到节约内存的作用。所有对象共享一个静态数据。
修饰之后的变量就不在堆内存中了,单独提取出来,每个对象都能访问得到。被所有对象所共享,可以起到节约内存的作用。
当成员被静态修饰后,就多了一种调用方式,除了可以被对象调用外,还可以直接被类名调用,写法格式是“类名.静态成员”。
特有内容随着对象存储,不可以用静态修饰。
//内存中的方法区(或者叫共享区/数据区):这片区里面还会有更细致的划分。
类中的方法,类中的共享数据都存放在这里。
其实是类的东西都放在方法区中,方法区里有静态区和非静态区。
而且内存加载的顺序是先类,再对象,即先方法区,再堆内存。先静态区,再非静态区。
//static的特点:
1、随着类的加载而加载,随着类的消失而消失;说明他的生命周期最长;对内存一直占有空间,故不建议定义过度的静态变量,浪费内存。
2、优先于对象存在,可以没有建立对象而存在;需要用可以通过类调用或者建立对象后用对象调用。
3、被所有对象所共享,
4、可以直接被类名所调用。
//对象没有建立之前,是不可能有里面的元素出现的。就算在类中有定义一个变量,因为没被赋值,没有实际意义,所以是不会在内存中有出现,只有对象建立后,赋予了内容才会有意义,才会在内存中出现。除非是静态的成员变量。
//静态变量,非静态变量;成员变量,实例变量(实例就是对象,也可说为对象变量);静态的成员变量,类变量。
//实例变量和类变量的区别。
1、存放位置不同,类变量随着类的加载而存在于方法区中;实例变量随着对象的建立而存在于堆内存中;
2、生命周期不同;类变量生命周期最长。随着类的消失而消失;实例变量生命周期随着对象的消失而消失。
//静态的使用注意事项
1、静态方法只能访问静态成员(变量和方法)。没有被对象调用的非静态方法也是访问不到。
2、非静态方法既可以访问静态也可以访问非静态。
3、静态方法中不可以定义this super关键字,因为静态优先于对象的存在,所以静态方法中不可以出现this。
静态随类先存在,非静态随对象而存在。
静态有利有弊
利:对对象的共享数据进行单独空间的存储,节省空间,没有必要每个对象中都存储一份,可以直接被类名直接调用。
调用者只有两,对象和类。
弊端:生命周期过长,访问出现局限性。(静态虽好,只能访问静态)
注意:主函数是静态的。
主函数是一个特殊的函数,作为程序的入口,可以被jvm调用,是程序的起始点。
主函数的定义:
public:代表着该函数的访问权限是最大的;
static:代表着主函数随着类的加载已经存在了;不需要再去调用了。jvm就默认你调用了。
void:主函数没有具体的返回值。
就是jvm在调用主函数。
main:不是关键字,但是是一个特殊的单词,可以被jvm识别。
关键字是不能用在函数名称的。
(String[] arr): 函数的参数,参数类型是一个数组,该数组中的元素是字符串,字符串类型的数组。存储字符串类型元素的数组。
主函数是固定格式的,才可以被jvm识别,只有后面一个变量名才可以被改写,他是一个变量名,可以随意改写的。 arguments 参数很多参数的意思。
jvm在调用主函数时,传入的是newString[0];
我们在调用函数时,是要往里面传与之对应的参数。现在的问题是jvm在调用main时到底调用的是什么呢?
引用数据类型无非就指向两个值,一个具体的,或者一个空null。
javac 启动的是编译器,java启动的是jvm
//什么时候使用静态。
要从两个方面下手:
因为静态修饰的内容有成员变量和函数,
什么时候定义静态变量(类变量)呢?
当对象中的出现共享数据时,该数据被静态所修饰,对象中的特有数据要定义成非静态存在于堆内存中。
共享数据/对象的特有数据。
什么时候定义静态函数呢?
当功能内部没有访问到非静态数据(或说对象的特有数据),那么该功能可以定义为静态的。
//静态的应用
把多个类中的同样的功能抽取出来封装到一个类当中。
功能的封装,
先把功能变成对象后,拿到了对象就拿到了这些功能。这就叫功能封装。
先把复用的功能做出来,以后的类就可以重复使用这些功能了。
每个应用程序中都有共性的功能,可以将这些功能进行抽取,独立封装,以便复用。
封装主要是封装成员(属性和功能)对象可以是任何的属性或者功能。
虽然可以通过建立arraytool的对象使用这些工具方法,对数组进行操作。
发现了的问题:
1、对象是用于封装数据的,可是arraytool对象并未封装特有数据,
2、操作数组的每一个方法都没有用到arraytool的对象的特有数据,
这是就考虑,让程序更严谨,是不需要对象的。
可以将arraytool中的方法都定义成static的,直接通过类名调用即可。
这个就叫做工具类,通常情况下,工具类都是定义的静态的。
将方法设为静态后,可以方便于使用,但是该类还是可以被其他程序建立对象的,为了更为严谨,强制让该类不能建立对象。可以通过将构造函数私有化完成。
还有一定要把能隐藏的功能和属性都隐藏起来。只把必须要公开的功能去公开。
//开发要养成习惯,都写说明书
接下来,将arraytool.class文件其他人,其他人只要将该文件设置到classpath的路径下,就可以使用该工具类,但是,很遗憾,该类中到底定义了多少个方法,对方都不清楚,因为该类没有使用说明书。
开始制作程序的说明书,java的说明书通过文档注释来完成。如:
/**
类的描述信息:
这是一个可以对数组进行操作的工具类,该类中提供了,获取最值,排序等功能。
(文档注释里有些特殊的标示,是可以直接被文档工具所提取并识别的)
@author 张三
@version v1.1
接下来就是对程序的功能进行描述
凡是public的修饰符都用文档注释描述,因为都可以被文档注释工具所提取。
。。。。。。。。。。。
*/
一个类中默认的会有一个空参数的构造函数,是系统自动生成的。
这个默认的构造函数的权限和所属类一致,如果类被public修饰,那么默认的构造函数也带public修饰符,如果类没有被public修饰,那么默认的构造函数,也没有被普遍了修饰,
默认构造函数的权限是随着类的变化而变化的。默认是看不见的。写了就没有默认了。
api帮助文档,应用程序接口文档。
工具类。
//静态代码块:
格式:
static
{
静态代码块的执行语句;
}
静态代码快的特征,随着类的加载而执行,只执行一次,并优先于主函数执行,因为他没有名字不需要调用,所以就直接执行。已经加进入内存了,如再被调用也不需要再加载了,就算引用也不会被执行了。
用于给类进行初始化的。一个类进内存不需要对象的情况下,这个类先要做些什么事情,相对的少用一些。
调用类的功能要会被加载,只要在用到他当中的功能才会被加载,否则是不会被加载的。
建立一个对象,赋值的顺序是:默认初始化,——显示初始化——构造代码块初始化——构造函数初始化。
只要静态代码块执行完后,对象才会开辟空间和分配地址值。
Person p= new Person(“张三”,20);
这句话都做了些什么事情?
1、因为new用到了Person.class。所以会先找到person。class文件并加载到内存中。
2、执行该类中的static代码块,如果有的话,给person。class类进行初始化;
3、在堆内存中开辟空间,分配内存地址值;
4、在堆内存中建立对象的特有属性,并进行默认初始化;
5、对属性进行显示初始化,
6、对对象进行构造代码块初始化;
7、对对象进行对性的构造函数初始化
8,将内存地址赋值给栈内存中的p变量。
方法区是优先于对象存在的,肯定是先于对象产生新的空间。
方法区是先加载了,相对于对象。堆内存里的东西还没有时,方法区就已经有内容了。优先于对象加载。
this是不可能用在静态里面的的。因为静态里面的特性都是共享的。
先引用某功能,可以先对其建立对象。
调用方法和属性,就先建立对象把他框进来这个思想。
//扩展知识——设计模式
所谓模式,就是解决某一类问题最好最行之有效的方法。由老外四个人一共总结了java的23种通用模式。
如果深入学习可以找些外文资料,或者找《设计模式》的书。
不是偏代码的,而是偏思想的,因此使用各种语言。
把几种模式综合一下就称之为复杂的模式,我们称之为框架。
//单例设计模式:解决一个类中在内存只存在一个对象。
如某个程序的配置文件就是通过单例设计模式放在类当中的。
想要保证对象唯一
1、为了避免其他程序过多建立该类对象,先禁止其他程序建立该类对象。
2、为了让其他程序可以访问到该类对象,只好在本类中自定义一个对象;
3、为了方便其他程序对自行定义对象的访问,可以对外提供一些访问方式。
这三部怎么用代码体现呢?
1、将构造函数私有化,
2、在类中创建一个本类 对象;
3、提供一个方法可以获取到该对象。
总结:
对于事物该怎么描述,还怎么描述,当需要将该事物的对象保证在内存中唯一时,就将以上的三步加上即可。
单例设计模式有两种方式:
先初始化对象叫做饿汉式;
single类一进内存,就已经创建好了对象。
对象是方法被调用时,才初始化,也叫做对象的延时加载,称为懒汉式。
single类进内存,对象还没有存在,只有调用了getinstance方法时,才建立对象。
在实际开发中,一般都是用的饿汉式。因为他安全,简单。懒汉式会出现这方面的问题,因为cpu在某一时刻点上只会处理同一个程序的。多任务同时进行的本质就是因为cpu在几千分之一秒之间切换,cpu中的切换是随机的。可以用双重判断(多线程技术)来解决问题。
使用原则:定义单例时,建议使用饿汉式。
方法要被类访问,就要先静态。而且类中的成员变量先私有化一下。静态的类可以直接被调用。表示共享。要想被调用只有两种方法,第一就是对象,第二就是类。
对象是一定会在堆内存里的。
先引用某功能,可以先对其建立对象。
调用方法和属性,就先建立对象把他框进来这个思想。