在所有定义的方法和属性上实际上都可以使用static关键字。
static属性
范例: 定义一个人的类,并设置他的国家
class Person {
private String name;
private int age;
String country = "中国"; //为了后面操作方便,暂时不封装
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getInfo() {
return "姓名:" + this.name + ", 年龄:" + this.age + ",国家:" + this.country;
}
}
public class TestDemo {
public static void main(String[] args) {
Person p1 = new Person("张飒", 10);
Person p2 = new Person("李斯", 14);
Person p3 = new Person("王武", 16);
System.out.println(p1.getInfo());
System.out.println(p2.getInfo());
System.out.println(p3.getInfo());
}
}
以上的定义模式是以前使用过的,而这个时候三个对象进行的内存分配如下:

既然现在描述的都是中国人,那么理论上这些country属性都是相同的,所以此时发现每一个对象的country属性被重复保存。如果假设国家的名称都改变了,按照以上的存储模式就会出现一个问题。假设当前Person类产生了10亿个对象,更改他们的国家的话需要一个一个对象地更改。
那么现在就可以发现传统属性所具备的特征就是保存在堆内存之中,并且每一个对象独享此属性。可是同样的概念不适合当前的环境,所以最好的做法是将country属性变为共享属性,只要一次修改就可以影响到所有的对象。那么要如果描述这样的共享属性,则只需要在属性前追加一个static关键字即可。
范例: 定义static属性
class Person {
private String name;
private int age;
static String country = "中国"; //为了后面操作方便,暂时不封装
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getInfo() {
return "姓名:" + this.name + ", 年龄:" + this.age + ",国家:" + this.country;
}
}
public class TestDemo {
public static void main(String[] args) {
Person p1 = new Person("张飒", 10);
Person p2 = new Person("李斯", 14);
Person p3 = new Person("王武", 16);
p1.country = "China";
System.out.println(p1.getInfo());
System.out.println(p2.getInfo());
System.out.println(p3.getInfo());
}
}
当程序中使用了static关键字进行定义之后,那么此属性将不会保存在堆内存里面,会保存在一个全部数据区的内存空间之中,并且所有的对象都可以进行该数据区的访问。
既然现在使用的是共享属性了,这个时候代码就会出现一个问题,共享属性可以通过一个对象修改吗?对于static也会将其称为类属性,而所有的类属性都可以利用类名称直接调用。Person.country = "China";
所有的非static属性必须在产生实例化对象之后才可以使用,而所有static的属性不收实例化对象的限制,也就是是否有对象与static属性操作无关。
选择: 关于static属相与非static属性定义的选择?
- 在定义类99%的情况下不会考虑
static属性的 - 如果需要描述共享属性的概念,或者不希望受到实例化对象控制的时候使用
static属性
static方法
由static定义的属性可以类名称直接访问,那么同样用static定义的方法也可以直接被类名称进行访问。同样不收到实例化对象的控制。
范例: static定义的方法
class Person {
private String name;
private int age;
static String country = "中国"; //为了后面操作方便,暂时不封装
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 + ",国家:" + this.country;
}
}
public class TestDemo {
public static void main(String[] args) {
Person.setCountry("民国"); // 没有实例化对象
Person p1 = new Person("张飒", 10);
System.out.println(p1.getInfo());
}
}
虽然类中已经存在有static方法和非static方法了,那么对于两者的互相调用存在限制
- 所有的
static方法不允许调用非static定义的属性或方法。 - 所有的非
static方法允许访问static属性或方法
因为所有的static方法可以在没有实例化对象的时候访问,而所有的非static方法在有实例化对象产生之后才可以操作。
使用static的属性是共享目的(因为属性需要封装),但是使用statci的方法的目的只有一个:某些方法需希望不受到类的限制,即可以在没有使用实例化对象的时候进行执行。
主方法组成
如果一个方法定义在主类之中,并且由主方法直接调用,那么该方法的定义语法是:public static 返回值类型 方法名称(参数列表) {}。
后来写到类结构的时候并没有使用static,其主要原因也是因为static方法的限制。
public class TestDemo {
// static方法是独立于类之外的使用原则
public static void main(String[] args) { //static方法
print();
}
public static void print() { //static
System.out.println("hello world");
}
}
如果此时print()方法上没有写上static,那么表示的就是一个非static方法,所有的非static方法必须通过类对象才可以使用。但是也可以通过new TestDemo().print()进行调用。
但是反过来看也必须清楚一个问题,Java中给出的主方法名字时最长之一,其组成意义如下:
public:表示是公共的,主方法作为起点必须可以访问;static:执行Java程序的时候执行的是一个类名称,所以表示不受实例化限制;void:主方法是一切的起点,既然开始了就走吧;main:是一个系统定义好的方法名称;String args[]表示该类执行时所需的相关参数。
范例: 取得执行参数
public class TestDemo {
public static void main(String[] args) {
//所有的参数类型都是String型
for(int x = 0; x < args.length; x++) {
System.out.println(args[x]);
}
}
}
参数的设置:java TestDemo hello world !。
如果现在的参数内容本身有空格,那么需要使用双引号:java TestDemo “hello” “world !”。
static应用
static属性最大功能是进行共享的操作,所以在这一基础上可以使用static做一个对象产生的技术统计。新对象一定要使用构造方法完成,所以可以在构造方法中实现。
范例: 对象产生个数统计
class Person {
private static int count = 0; //保存对象产生个数
public Person() {
System.out.println("对象个数:" + ++count);
}
}
public class TestDemo {
public static void main(String[] args) {
new Person();
new Person();
}
}
那么也可以在以上的程序基础上做一个更加简答的扩充,假设:Person类中有一个name属性以及两个构造方法,其中一个构造方法可以接受外部传递的name属性内容,而另外一个构造方法是无参构造,一旦使用无参构造就希望可以自动为类中的name属性做一个自动赋值,例如:“NONAME-1”。那么此时就可以继续使用static属性控制。
class Person {
private String name;
private static int count = 0; //保存对象产生个数
public Person() { //需要由程序自己来设置内容
this("NONAME-" + count++); //调用本类有参构造
}
public Person(String name) { //由外部传递属性内容
this.name = name;
}
public String getName() {
return this.name;
}
}
public class TestDemo {
public static void main(String[] args) {
System.out.println(new Person().getName());
System.out.println(new Person("Mj").getName());
System.out.println(new Person().getName());
}
}
这种自动为属性命名的操作由static属性控制。
总结
static定义的属性和方法并不是进行类设计的首要选择;static的属性或方法不受到类的实例化对象限制,可以有类名称直接使用。
本文深入解析Java中的static关键字,探讨其在属性和方法上的应用,包括如何创建共享属性,实现对象计数,以及static方法的独立性和调用限制。同时,文章提供了多个代码示例,帮助读者理解static在实际编程中的作用。
2199

被折叠的 条评论
为什么被折叠?



