java中有四块内存空间,名称和作用如下:
- 栈内存空间:保存引用的堆内存空间的地址;
- 堆内存空间:保存每个对象的具体属性内容;
- 全局数据区:保存static类型的属性;
- 全局代码区:保存所有的方法定义;
类由属性和方法构成,每一个对象分别拥有各自的属性内容,如果类中的某个属性希望定义为公共属性,可以在声明属性前加上static关键字。
public class Book {
private String title;
private double price;
public static String pub = "清华大学出版社";//所有对象的共同属性,为了方便操作,暂不封装
public Book(String title, double price) {
this.title = title;
this.price = price;
}
public String getInfo(){
return "书名:"+this.title+". 价格:"+this.price+".出版社:"+this.pub;
}
}
public class Application {
public static void main(String[] args) {
Book ba = new Book("learn java",34.4);
Book bb = new Book("learn python",43.4);
System.out.println(ba.getInfo());
System.out.println(bb.getInfo());
System.out.println("=============");
ba.pub = "TongJi publication";
System.out.println(ba.getInfo());
System.out.println(bb.getInfo());
}
}
执行结果为:
书名:learn java. 价格:34.4.出版社:清华大学出版社
书名:learn python. 价格:43.4.出版社:清华大学出版社
=============
书名:learn java. 价格:34.4.出版社:TongJi publication
书名:learn python. 价格:43.4.出版社:TongJi publication
因为普遍前有static,这个属性将成为公共属性,也就是说任何一个对象修改了此属性的内容都将影响到其他对象。既然static是一个公共属性的概念,那么由一个普通的对象去修改此属性就不太合适,最好由所有对象的公共代表来修改此属性,这个公共代表就是类。所以static属性可以通过类名称来直接调用。
Book.pub = "Tongji publication";
static属性和非static属性的最大区别就是:所有的非static属性都必须产生实例化对象才可以访问,但是static属性不受实例化对象的控制,也就是说,在没有实例化对象产生的情况下,依然可以使用static属性。不过static属性不常出现,一般只有在描述共享属性概念或者是不受实例化对象限制的属性时才会使用,不多数情况下依然使用非static属性。
同样道理,可以使用static属性定义普通方法,并在没有实例化对象产生的情况下直接通过类名称调用。
package testStatic;
public class Book {
private String title;
private double price;
private static String pub = "清华大学出版社";
public Book(String title, double price) {
this.title = title;
this.price = price;
}
public static void setPub(String p){//定义static方法可以直接由类名称调用
this.pub = p;
}
public String getInfo(){
return "书名:"+this.title+". 价格:"+this.price+".出版社:"+this.pub;
}
}
public class Application {
public static void main(String[] args) {
Book.setPub("TongJi publication");//在没有对象产生的时候调用
Book ba = new Book("learn java",34.4);
Book bb = new Book("learn python",43.4);
System.out.println(ba.getInfo());
System.out.println(bb.getInfo());
}
}
执行结果为:
书名:learn java. 价格:34.4.出版社:TongJi publication
书名:learn python. 价格:43.4.出版社:TongJi publication
以上例子可以看出static定义的属性和方法都不受实例化对象的控制,也就是说都属于独立类的功能,但是这样就产生了两种属性和两种方法:
- static方法只能调用static属性和方法,不能直接访问非static属性或方法;
- 非static方法可以访问static的属性和方法,不受任何限制;
主方法的进一步解释:
package testStatic;
/*public class testDemo {
public static void main(String[] args) {
fun();
}
因为主方法是一个static方法,所以它只能调用static方法,因此定义fun函数的时候必须使用static关键字
public static void fun(){
System.out.println("hello");
}
}*/
public class testDemo{
public static void main(String[] args) {
new testDemo().fun();
}
//fun函数是一个非static方法,必须通过实例化对象才能调用
public void fun(){
System.out.println("hello");
}
}
类中什么时候定义static方法呢?
答:产生实例化对象是为了在堆中保存属性信息,所以如果一个类中没有产生属性,就没有必要去开辟堆内存保存属性内容了,这时就可以考虑类中的方法全部使用static属性。比如常见的Math类,提供的是科学计算的方法,不需要产生实例化对象,所以大量使用了static修饰符。