------- android培训、java培训、期待与您交流! ----------
以下仅为个人平时学习笔记,可能有有错误的地方,希望有看到者提出来,共同讨论,谢谢!
1.为了节省堆内存,将该类中所有实例化对象属性值相同的属性声明为static,这样,所有从该类实例化的对象
都使用同一个堆内存中属性值,不会每实例化一个对象就相应生成一次该属性并赋值。
2.static:是一个修饰符,用于修饰成员(成员变量,成员函数)。
3.static的特点:
a.随着类的加载而加载,随着类的消失而消失;
当类被加载到内存中时,内存中就为该类中的静态成员开辟好了空间了.
b.优先于对象存在;
c.被所有对象所共享;
d.可以直接被类名所调用.
4.实例变量和类变量的区别:
a.存放位置
类变量随着类的加载而存在于方法区中;
实例变量随着对象的建立而存在于堆内存中.
b.生命周期
类变量生命周期最长,随着类的消失而结束.
实例变量生命周期随着对象的消失而结束.
5.静态使用注意事项:
a.静态方法只能访问静态成员(方法、变量);
b.非静态方法可以访问静态成员(静态先于非静态出现)
c.静态方法中不能定义this、super关键字(因为静态方法优先于对象存在,而this代表对象)。
6.静态优缺点:
优点:
a.对对象的共享数据进行单独空间的存储节省空间(没有必要每一个对象中都存储一份)。
b.可以直接被类名调用。
缺点:
a.生命周期过长;
b.访问出现局限性(静态只能访问静态)。
7.特别注意:
主函数是静态的(public static void main(String[] args){}),
主函数是一个特殊的函数,作为程序的入口函数,可以被jvm调用。
8.什么时候使用静态?
a.对于静态变量:
当对象中出现共享数据时候,该属性被定义成static(特有数据要定义为非静态).
b.对于静态方法:
当功能内部没有访问到非静态数据(对象特有的数据),此时该功能可以定义为static的.
(有时候实例化一个对象,来调用该对象中的某一方法,但是该方法却并未访问该对象中任何
的非静态数据,如果实例化对象再调用方法,实例化对象就没有意义了,此时方法定义成static
的,直接通过类名.方法名调用)
**************************************静态的应用********************************************
1.每一个应用程序中都有共性的功能,可以将这些共性的功能进行抽取,独立封装成工具类,以便以后复用。
(例如对于数组的操作)
2.注意:
而,如果定义的工具类中方法并没有访问到该类中的特有数据,那么该类中这样的方法定义为static的即可。
而且如果该工具类中的所有方法均定义为了静态的,那么为了更为严谨,可以讲该类的构造方法定义为私有的
禁止从该类实例化对象。
************************************静态代码块************************************************
1.特点:
a.随着类的加载而执行,只执行一次。(用于给类初始化)
例子如下:
public class Test_Static
{
static
{
System.out.println("b");
}
public static void main(String[] args)
{
new StaticDemo();
new StaticDemo();
System.out.println("over");
}
static
{
System.out.println("c");
}
}
class StaticDemo
{
static
{
System.out.println("a");
}
}
输出结果为:b
c
a
over
*注意:
a.仅仅写StaticDemo sd = null;并未将StaticDemo类加载进内存中,所以并不能执行其
中的静态代码块内容。
b.在哪涉及到有静态代码块的类,从哪开始加载该类进内存。(有时候调用到该类是在某一
普通语句之后,那就要执行完该语句再执行该类的加载)
c.静态代码块先于构造函数执行.(因为静态代码块随类的加载而执行,但构造函数要在实例化
对象时候才会执行)
d.构造代码块初始化对象.
*********************************对象初始化过程*********************************
class Person
{
private String name;
private int age;
private static String country = "cn";
static
{
System.out.println("静态代码块");
}
{
System.out.println(name+"--"+age);
}
Person()
{}
Person(String name,int age)
{
this.name = name;
this.age = age;
}
public void setName(String name)
{
this.name = name;
}
public void speak()
{
System.out.println(this.name+"----"+this.age);
}
public static void showCountry()
{
System.out.println("country="+country);
}
}
**new Person("zhangsan",23)初始化顺序全局变量-->>构造代码块-->>构造函数初始化
输出为:静态代码块
null--0
Person p = new Person("zhangsan",23);
1.因为new用到了Person.class,所以会先找到Person.class文件并加载到内存中;
2.如果有静态代码块的话,执行该类的静态代码块,给Person类惊醒初始化;
3.在堆内存中开辟空间,分配内存地址;
4.在堆内存中建立对象的特有属性,并进行默认初始化.
5.对属性进行显示初始化;
6.对对象进行构造代码块初始化;
7.对对象进行对应的构造函数的初始化;
8.将内存地址赋给栈内存中的p变量.
*注意: 方法区(静态属性、方法)优先于对象存在.