第四章:static关键字
第十二课:声明static属性
1.在Java中什么是static
static是一个关键字,可以用来修饰方法和类的属性,当用static修饰类的属性时,被修饰的属性将和普通属性有以下区别:
(1.内存中的存放位置不同,普通属性存放在堆内存中,被static修饰的属性存放在全局数据区,
(2.普通属性在堆内存中只要新建了一个实例化对象,就会产生一份新的属性值,而被static修饰的属性在全局数据区有且仅有一份,不会随着实例化对象的产生而增多,
(3.普通属性不能通过类名直接调用,必须通过类的实例化后再调用,而被static修饰的属性可以直接被类调用修改,也可以被类的实例化对象调用修改(不推荐),被static修饰的属性一般是用于在一个类的公共属性上面,这种情况一般很少出现。
2.传统属性代码与使用static修饰的属性代码对比分析
传统代码:
java
public class Main {
public static void main(String[] args) {
//给类实例化三个对象
Person person1=new Person("张三",10);
Person person2=new Person("李四",12);
Person person3=new Person("王二",15);
//修改国家名称
person1.country="中华人民共和国";
person2.country="中华人民共和国";
person3.country="中华人民共和国";
//输出三个实例化对象的信息
System.out.println(person1.getInfo());
System.out.println(person2.getInfo());
System.out.println(person3.getInfo());
}
}
class Person{
//姓名
private String name;
//年龄
private int age;
//这是一个所有实例化对象的公共属性,即这是一个来自一个国家的类
String country="中华民国";
//构造函数
public Person(String name, int age){
this.name = name;
this.age = age;
}
//setter、getter方法
public void setName(String name){
this.name=name;
}
public void setAge(int age){
this.age=age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
//类的信息输出
public String getInfo(){
return "姓名:"+this.name+"\n"
+"年龄:"+this.age+"\n"
+"国家:"+this.country;
}
}
输出:
有static关键字修饰属性的代码:
java
public class Main {
public static void main(String[] args) {
//给类实例化三个对象
Person person1=new Person("张三",10);
Person person2=new Person("李四",12);
Person person3=new Person("王二",15);
//修改国家名称
// person1.country="中华人民共和国";
// person2.country="中华人民共和国";
// person3.country="中华人民共和国";
//修改国家名称
Person.country="中华人民共和国";
//输出三个实例化对象的信息
System.out.println(person1.getInfo());
System.out.println(person2.getInfo());
System.out.println(person3.getInfo());
}
}
class Person{
//姓名
private String name;
//年龄
private int age;
//这是一个所有实例化对象的公共属性,即这是一个来自一个国家的类
static String country="中华民国";
//构造函数
public Person(String name, int age){
this.name = name;
this.age = age;
}
//setter、getter方法
public void setName(String name){
this.name=name;
}
public void setAge(int age){
this.age=age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
//类的信息输出
public String getInfo(){
return "姓名:"+this.name+"\n"
+"年龄:"+this.age+"\n"
+"国家:"+this.country;
}
}
输出:
对比分析:两段代码主要的区别就是对属性country的处理,传统代码中country没有用static修饰,那么它和其它基本属性一样都是存在堆内存中,只有对象实例化后才能对其进行操作,且多次实例化会产生多次的country值,要修改它的值必须所有的实例化对象依次修改;但在用static修饰的代码中,country属性就不再存放在堆内存里面,而是放在了全局数据区,且只存了一份,可以用类名直接调用修改,各个实例化对象也能直接调用使用或者修改。对static修饰的属性的代码进行内存分析如下:
第十三课:声明static方法
1.static方法和非static方法的比较
static方法只能调用static属性或static方法;
非static方法允许调用static属性或static方法。
无论是static属性还是static方法都可以用类名直接调用,而一般属性和方法都必须在类实例化后用实例化对象进行调用。
注意:static定义的属性和方法都不是程序设计之初需要考虑的内容,只有在回避实例化调用并且描述公共属性下才会考虑使用static定义的方法和属性。
代码示例:
java
public class Main {
public static void main(String[] args) {
//static的方法里面可以使用static方法
Person.setCountry("中华人民共和国");
//把属性country定义为private这句就不能用了
// Person.Country;
//输出country
System.out.println(Person.getCountry());
//测试static方法调用static方法
Prictise();
}
public static void Prictise(){
System.out.println("测试static方法调用static方法");
}
}
class Person{
//姓名
private String name;
//年龄
private int age;
//这是一个所有实例化对象的公共属性,即这是一个来自一个国家的类
private static String country="中华民国";
//构造函数
public Person(String name, int age){
this.name = name;
this.age = age;
}
//setter、getter方法
public void setName(String name){
//一般方法使用static方法
Person.setCountry(country);
this.name=name;
}
public void setAge(int age){
this.age=age;
}
public static void setCountry(String c){
System.out.println("测试static方法调用static属性");
country=c;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
public static String getCountry(){
return country;
}
//类的信息输出
public String getInfo(){
return "姓名:"+this.name+"\n"
+"年龄:"+this.age+"\n"
+"国家:"+this.country;
}
}
输出:
小总结:一般来说static方法就是为其他的static方法和static属性服务的,也可以在非static方法中使用,而static方法却不能出现一般属性和一般方法。
第十四课:static应用案例
程序要求:在实例化一个对象的时候要记录实例化对象的个数,当实例化对象使用无参构造时,给它一个初始值+个数。
代码:
java
public class Main {
public static void main(String[] args) {
new Book("java");
new Book("python");
new Book("javascript");
new Book();
new Book();
new Book();
System.out.println("一共创建了book的实例化对象"+Book.getCount()+"个");
}
}
class Book{
//书名
private String title;
//记录实例化对象的个数
private static int count=0;
//无参构造
public Book(){
this("NO-Title"+count);
}
//构造方法
public Book(String title){
this.title=title;
count++;
}
//setter,getter方法
public String getTitle(){
return this.title;
}
public void setTitle(String title){
this.title=title;
}
//此处必须定义为static方法,才能通过类名直接调用
public static int getCount(){
return count;
}
}
输出结果:
代码分析:要记录实例化对象的个数可以使用一个公共属性count来记录,并且在实例化对象时在构造方法中对count进行加一,另外注意在书写count属性的get方法时,要用static方法,不然在外部用类名称访问不到static的值。