static关键字
之前类只要实例化之后会在堆内存中保存一个对象所具备的全部的属性,也就是说,之前所声明类的属性是每一个对象单独拥有的。那么现在假设有以下一道程序,观察一下问题:
|
class Person{
String name ;
int age ;
String country = "南京" ;
public Person(String name,int age){
this.name = name ;
this.age = age ;
}
public void print(){
System.out.println("姓名:"+this.name+",年龄:"+age+",城市:"+country) ;
}
};
public class Demo02{
public static void main(String args[]){
Person p1 = new Person("张三",30) ;
Person p2 = new Person("李四",31) ;
Person p3 = new Person("王五",32) ;
p1.print() ;
p2.print() ;
p3.print() ;
}
}; |
从内存的分配角度来看,所有的对象都各自拥有一个country属性,那么现在假设说城市修改了,则意味着要修改全部的对象,如果此时对象已经有100个了,则要修改100遍,所以发现,对于这种大家共同拥有,共同相关的属性这样定义肯定不合适,应该定义成一个全局的,即:所有对象共同拥有同一个属性,这样以后修改就方便了。
只要在属性前面加上一个“static”关键字即可。
|
class Person{
String name ;
int age ;
static String country = "南京" ;
public Person(String name,int age){
this.name = name ;
this.age = age ;
}
public void print(){
System.out.println("姓名:"+this.name+",年龄:"+age+",城市:"+country) ;
}
};
public class Demo02{
public static void main(String args[]){
Person p1 = new Person("张三",30) ;
Person p2 = new Person("李四",31) ;
Person p3 = new Person("王五",32) ;
System.out.println("------------修改之前--------------") ;
p1.print() ;
p2.print() ;
p3.print() ;
p1.country = "北京" ;
System.out.println("------------修改之后--------------") ;
p1.print() ;
p2.print() ;
p3.print() ;
}
}; |
从此代码之中可以发现,所有的对象确实共同拥有同一个属性。所以使用static声明的属性称为全局属性,此属性保存在全局数据区之中。
但是会发现以上代码的调用虽然可以完成功能,但是有一点不妥:
p1.country = "北京" ; à 修改属性,但是一个静态属性是全局的,不能说一个对象改就全改,应该由所有对象的最高端进行修改,整个类就是最高端,所以一般在访问静态属性的时候都使用类名称.属性名称,这样的属性有时候也称为类变量。
static修饰符除了可以修饰属性之外,还可以声明方法,使用static声明的方法,称为类方法,此方法可以由类名称直接调用。
注意:
|
public static void setCountry(String country){
this.country = country ;
} |
不能使用this关键字访问static属性,因为this表示的是当前对象,当前对象中的属性,指的是存放在堆内存中的内容。而static是保存在全局数据区中,所以肯定无法找到。
|
class Person{
private String name ;
private int age ;
private static String country = "南京" ;
// 加入一个修改country属性的操作
public static void setCountry(String c){
country = c ;
}
public Person(String name,int age){
this.name = name ;
this.age = age ;
}
public void print(){
System.out.println("姓名:"+this.name+",年龄:"+age+",城市:"+country) ;
}
};
public class Demo03{
public static void main(String args[]){
Person p1 = new Person("张三",30) ;
Person p2 = new Person("李四",31) ;
Person p3 = new Person("王五",32) ;
System.out.println("------------修改之前--------------") ;
p1.print() ;
p2.print() ;
p3.print() ;
Person.setCountry("北京") ;
System.out.println("------------修改之后--------------") ;
p1.print() ;
p2.print() ;
p3.print() ;
}
}; |
进一步观察:类中可以有静态属性、非静态属性、静态方法、非静态方法、构造方法
· 静态方法能否访问静态属性?可以
· 静态方法能否访问非静态属性?不可以
· 静态方法能否访问非静态方法?不可以的
· 非静态方法能否访问静态属性?可以
· 非静态方法能否访问静态方法?可以
· 非静态方法能否访问非静态属性?可以
· 构造方法是否可以调用静态方法?可以
· 构造方法是否可以调用非静态方法?可以
进一步解释:
之前在将JAVA基础程序的时候,说过,方法的定义格式:
public static 方法的返回值 方法名称(参数){}
之前的方法调用是直接在main方法中完成的。
可以使用静态属性作为类产生对象的计数器(思路)
现在要完成这样一个功能,定义一个person类,里面如果没有明确的给出人的姓名,则自动对人进行编号,例如:person-0、person-1。。。,那么此时就必须使用静态属性完成。
|
class Person{
private String name ;
private int age ;
private static int count = 0 ;
// 所以在此处就可以为其赋上一个系统内定的名字
public Person(){
this.name = "person-"+count++ ;
}
public Person(String name,int age){
count++ ;
this.name = name ;
this.age = age ;
}
public void print(){
System.out.println("姓名:"+this.name+",年龄:"+age) ;
}
};
public class Demo05{
public static void main(String args[]){
Person p1 = new Person() ;
Person p2 = new Person() ;
Person p3 = new Person() ;
p1.print() ;
p2.print() ;
p3.print() ;
}
}; |
main方法的组成
public static void main(String args[])
· public:表示此方法可以被外部访问
· static:表示此方法可以由类名称直接调用(java Demo06)
· void:主方法是一切方法的开始点,所以不需要有返回值
· main:系统内定的方法名称,只要是通过java执行一个类,则此类自动找到main方法。
· String args[]:表示的是运行时的参数。
|- 通过参数可以完成不同的效果,当然此效果首先必须进行设置。
在java程序中,所有的参数是在运行之后自己设置的。
|
public class Demo06{
public static void main(String args[]){
for(int i=0;i<args.length;i++){
System.out.println(args[i]) ;
}
}
}; |
本文出自 51CTO.COM技术博客