1.static 的特点
1.static是一个修饰符,用于修饰成员。
2.static修饰的成员被所有的对象所共享。
3.static优先于对象存在,因为static的成员随着类的加载就已经存在了。
4.static修饰的成员多了一种调用方式,可以直接被类名所调用,类名.静态成员。
5.static修饰的数据是共享数据,对象中存在的数据是特有数据。
2.成员变量和静态变量的区别?
1.两个变量的生命周期不同。
成员变量随着对象的创建而存在,随着对象的回收而被释放。
静态变量随着类的加载而存在,随着类的消失而消失。
2.调用方式不同。
成员变量只能被对象调用。
静态变量可以被对象调用,还可以被类名调用。
3.别名不同。
成员变量也称为实例变量。
静态变量称为类变量。
4.数据存储位置不同。
成员变量数据存储在堆内存的对象中,所以也叫对象的特有数据。
静态变量数据存储在方法区(共享数据区)的静态区,所以也叫做对象的共享数据。
3.静态使用的注意事项
1.静态方法只能访问静态成员(包含方法和成员)。(非静态可以访问非静态,又可以访问静态)
2.静态方法中不可以使用this或者super关键字。
3.主函数是静态的。
class Person
{
String name;//实例变量,成员变量
static String country = "CN";//类变量
public void show()
{
System.out.println(Person.country+":"+this.name);
}
}
class staticDemo
{
int num = 4;
public static void main(String[] args)
{
String country = Person.country;//直接利用类名调用类中的静态变量,静态变量比对象先存在
System.out.println(country);
new staticDemo().show();//要在静态方法中调用非静态方法必须要有对象
}
public void show()
{
System.out.println(num);
}
}
4.静态什么时候用?
1.静态变量。
当分析对象中所具备的成员变量的值都是相同的(即变量的值是共性的)。这时这个成员就可以被静态修饰。
只要数据在对象中都是不同的(即特性),就是对象的特有数据,必须存储在对象中,是非静态的。
如果是相同的数据(是共性),对象不需要修改,只需使用即可,不需要存储在对象中,定义为静态的。
2.静态函数
函数是否用静态修饰,就参考一点,就是该函数功能是否访问到对象中的特有数据。
简单的说,从源代码看,该功能是否需要访问非静态成员变量,如果需要,该功能是非静态的。
如果不需要,就可以将该功能定义成静态的,当然也可以定义成非静态的,但是非静态需要被对象调用,而仅创建对象调用非静态的没有访问特有数据的方法,该对象的创建是没有意义的,而且还浪费了堆内存。
5.有关静态执行过程的演示
class Person//定义一个Person的类
{
private static String country = "CN";
private String name;
private int age;
Person(String name, int age)//构造函数对对象变量初始化
{
this.name = name;
this.age = age;
}
void show()//定义了一个非静态的方法
{
System.out.println(Person.country+":"+this.name+":"+this.age);
}
static void method()//定义了一个静态的方法
{
System.out.println(Person.country);
}
}
class staticDemo2
{
public static void main(String[] args)
{
Person.method();//调用类的静态方法
Person p = new Person("Java",20);//建立一个Person类的对象
p.show();//调用对象的show方法
}
}
程序运行的过程;
1.首先找到含有主函数的类,把staticDemo2类加载到方法区(共享数据区)内,public static void main(String[] args)存放在静态方法区内。
main()函数进栈区。
2.执行Person.method()这一句;首先jvm会把Person类加载到方法区内(共享数据区),其中Person(String name, int age){代码}放在非静态方法区内,
void show(){代码}放在非静态方法区内,static void method(){代码}放在静态区内,类变量country也会放在静态区内。
jvm会从静态区中找到method(),method()进栈区执行System.out.println(Person.country),从静态区内找到类变量(也是静态变量)country,打印。出栈
3.执行Person p = new Person("Java",20),首先在堆区放入age,name成员变量,然后Person()构造函数进栈区,在栈区创建局部变量age=20,
name = "Java",然后找到调用Person()的对象,把局部变量的值赋给堆区的相应的变量。出栈。最后p指向对象实体。
4.执行p.show(),在对象p中找到show()方法,然后show()入栈,执行打印操做(从静态方法区找到country,在p对象的堆区找到age和name输出),出栈
5.main执行完毕出栈。各区中的变量和方法也被释放。
6.主函数的分析
public static void main(String[] args)
主函数的特殊之处:
1.格式是固定的
2.被jvm所识别和调用
public:因为权限必须最大;
static;不需要对象的,直接用主函数所属类名调用即可
void;主函数没有具体的返回值
main;函数名,不是关键字,只是一个jvm识别的固定名字
String[] args:这是主函数的参数列表,是一个数组类型的参数,而且元素都是字符串类型的。
*/
class MainDemo
{
public static void main(String[] args)//JVM往主函数里面传的是一个 new String[0];
{
System.out.println(args);//[Ljava.lang.String;@555590
System.out.println(args.length);
for(int i = 0; i<args.length; i++)
System.out.println(args[i]);
}