static的详细讲解

以前自己对static这个关键字了解的一直不是很透彻,通过查阅资料,自己才更深刻的理解,今与众位分享:


static关键字在类中可以声明属性或方法。声明的属性将称为全局属性,声明的方法将成为类方法。


1、声明属性

通过两个例子进行比较

代码1:

class Person {
	private String name;
	private int age;
	String country = "A 城";

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String getInfo() {
		return "姓名:" + this.name + ",年龄:" + this.age + ",城市:" + country;
	}
};

public class StaticDemo01 {
	public static void main(String args[]) {
		Person per1 = new Person("张三", 20);
		Person per2 = new Person("李四", 21);
		Person per3 = new Person("王五", 22);
		System.out.println(per1.getInfo());
		System.out.println(per2.getInfo());
		System.out.println(per3.getInfo());
	}
};


但是以上的程序存在了一个问题,现在的所有人的城市都是在A城,但是后来这个城市的名字修改成了X城,那么如果现在已经产生了500000个Person对象,肯定现在要修改50000次对象中的country属性,因为按照内存的分配来讲,每一个对象都单独占着各自的country的属性。

现在以上的设计根本就无法满足,因为对于country属性而言,肯定是所有对象都是一样的,而且如果按照以上的设计,每个对象占用每个对象自己的country属性的话,则肯定会造成内存空间的浪费,那么就可以将country属性设置成一个公共属性,那么公共属性就可以使用static进行操作。 

代码2:

class Person {
	private String name;
	private int age;
	static String country = "A城";

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String getInfo() {
		return "姓名:" + this.name + ",年龄:" + this.age + ",城市:" + country;
	}
};

public class StaticDemo02 {
	public static void main(String args[]) {
		Person per1 = new Person("张三", 20);
		Person per2 = new Person("李四", 21);
		Person per3 = new Person("王五", 22);
		System.out.println(per1.getInfo());
		System.out.println(per2.getInfo());
		System.out.println(per3.getInfo());
		System.out.println("---------------------");
		per1.country = "B城";
		System.out.println(per1.getInfo());
		System.out.println(per2.getInfo());
		System.out.println(per3.getInfo());
	}
}
 现在发现修改了一个对象中的country属性之后,所有对象的country属性都发生了变化,那么country属性肯定就成为了公共属性,所有的对象可以同时拥有,但是一般而言这些公共属性虽然可以使用普通的对象调用,可一般不这样操作,而是通过所有对象的最大级  —— 类,完成调用。

由于全局属性拥有可以通过类名称直接访问的特点,所以这种属性又称为类属性。


2、声明方法:

  对于属性而言,不管是何种属性都要考虑封装,对于全局属性也不例外,那么既然全局属性可以通过类名称访问,那么也可以使用static定义一个“类方法”,很明显此方法也可以通过类名称直接访问。 

class Person {
	private String name;
	private int age;
	private static String country = "A 城";

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public static void setCountry(String c) {
		country = c;
	}

	public String getInfo() {
		return "姓名:" + this.name + ",年龄:" + this.age + ",城市:" + country;
	}
};

public class StaticDemo03 {
	public static void main(String args[]) {
		Person per1 = new Person("张三", 20);
		Person per2 = new Person("李四", 21);
		Person per3 = new Person("王五", 22);
		System.out.println(per1.getInfo());
		System.out.println(per2.getInfo());
		System.out.println(per3.getInfo());
		System.out.println("---------------------");
		Person.setCountry("B城");
		System.out.println(per1.getInfo());
		System.out.println(per2.getInfo());
		System.out.println(per3.getInfo());
	}
};


3、static的使用注意

  static本身声明方法或声明属性,但是在方法的访问上本身也存在着问题。 
   1、  使用static声明的方法,不能访问非static的操作(属性或方法) 
   2、  非static声明的方法,可以访问static声明的属性或方法 

代码3:

class Person {
	static String country = "A城";
	private String name;

	public static void setCountry(String c) {
		print();
		System.out.println(name);
	}

	public void print() { // 非static方法
	}
};

此代码就会报错。


代码4:

class Person {
	static String country = "A城";
	private String name;

	public static void setCountry(String c) {
	}

	public void print() { // 非static方法
		setCountry("");
		System.out.println(country);
	}
};
此代码不会报错。


那么,为什么呢? 
   1、  如果说现在一个类中的属性或方法都是非static类型的,肯定是要有实例化对象才可以调用。 
   2、  static声明的属性或方法可以通过类名称访问,可以在没有实例化对象的情况下调用。 
  当一个实例化对象产生之后,可以调用所有的非static的操作,那么肯定也就可以调用所有的static操作。 

代码5:

public class StaticDemo05 {
	public static void main(String args[]) {
		new StaticDemo05().printInfo();
	}

	public void printInfo() {
		System.out.println("Hello World!!!");
	}
};

此代码没有任何问题。

在静态方法中若新建一个对象,用这个对象是可以调用非静态方法 的。

4、扩展

既然static的属性是所有对象所共同拥有的,那么就可以利用此特点完成一个自动命名的功能。 

代码6:

class Book {
	private String name;
	private static int count = 0;

	public Book() {
		this.name = "无名字  - " + ++count;
	}

	public Book(String name) {
		this.name = name;
	}

	public String getName() {
		return this.name;
	}
}

public class StaticDemo06 {
	public static void main(String args[]) {
		System.out.println(new Book("JAVA基础").getName());
		System.out.println(new Book().getName());
		System.out.println(new Book().getName());
		System.out.println(new Book().getName());
		System.out.println(new Book("Oracle").getName());
	}
};




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值