---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
static关键字
由同一个类创建的所有对象共享,在内存中只加载一次
静态修饰的成分存储在方法区或者共享区或者数据区
尽量少设置过多的静态,会占用太多的空间
随着类的加载而加载,也就是说类加载一次,static修饰的成员也只加载一次
类存在则静态存在,类消失则静态消失
优先于对象存在,也就是说静态先存在,然后对象才存在
被所有由同一个类所创建的所有对象共享
可以直接被类名所调用,也就是说不需要通过创建对象再由对象调用,而是直接:类名.静态成员
实例变量和类变量(静态变量)的区别:
存放位置
类变量随着类的加载而存在于方法区中
实例变量随着对象的建立而存在与堆内存中
生命周期
类变量的生命周期最长,随着类的消失而消失
实例变量生命周期随着对象的消失而消失
静态使用注意事项:
静态方法只能访问静态成员
非静态方法可以访问静态成员
静态方法中不可以定义this(),super()
静态方法中不可以出现“this.*”
静态有利有弊:
有利:对对象的共享数据进行单独空间的存储,没有必要每一个对象中都存储一份,节省空间
可以直接被类名调用
弊端:生命周期过长
访问出现局限性(静态虽好,只能访问静态)
什么时候使用静态?
当对象出现共同共享数据时,比如:同一个国家的人的国籍
而对象中的特有数据(对象自定义的)要定义成非静态存在与堆内存中
什么时候定义静态函数?
当功能内部没有访问到非静态数据(对象的特有数据)
静态的应用
例如:程序员自己开发的一些工具类,然后静态调用
//写一个工具类
class ArrayTool
{
//私有化构造函数,外界将无法将ArrayTool实例化
private ArrayTool(){}
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];
}
}
用main函数调用
class Demo
{
public static void main(String[] args)
{
int[] arr = {2,3,4,8,1,43,5};
//调用静态方法
ArrayTool.getMax(arr);
}
}
静态代码块:
格式:
static
{
执行语句
}
特点:
随着类的加载而执行,只执行一次,即使调用两次含有静态代码块的类也只会执行第一次,而第二次不执行
优先于主函数
构造代码块:
对象一建立就运行,但是优先于构造函数
每次实例化对象不管是有参的还是无参的都得执行,这样就提高了代码的的重用性
class Test
{
//构造代码块
{
//要执行的代码
}
Test(){}//无参构造函数
Test(int i){}//有参构造函数
}
类初始化的时候会执行到的代码块
static
{
执行语句
}
构造函数初始化代码块,也就是建立对象的时候会执行到的代码块
{
执行语句
}
因此静态代码块里面不能引用非静态成员,静态代码块和静态函数被加载的时候根本找不到引用的非静态成员,会发生空引用异常
对象初始化过程
1、因为new用到了Person.class,所以会先找到Person.class文件并加载到内存中
2、执行该类中的static代码块,如果有的话,给Person.class类进行初始化
3、在堆内存中开辟空间,分配内存地址
4、在堆内存中建立对象的特有属性,并进行默认初始化(非静态成员)
5、对属性进行显示初始化(赋值)
6、对对象进行构造代码块初始化
7、对对象进行对应的构造函数初始化
8、将内存地址赋值给栈内存中的xxx变量
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------详细请查看:www.itheima.com