類變量與類方法,咱們習慣也將其稱爲靜態變量與靜態方法。java
經過一個實際案例來了解,爲何須要使用靜態變量。數組
聲明一個學生類,每建立一個學生對象,統計學生的人數。this
public class Test{ public static void main(String[] args){ int count = 0; //局部變量,累積計數 Student stu1 = new Student("小范"); count ++; Student stu2 = new Student("小黃"); count ++; Student stu3 = new Student("小雨"); count ++; System.out.println("目前學生人數有:" + count); } } class Student{ private String name; public Student(String name){ this.name = name; } }
經過這個案例咱們能夠看到,count做爲一個局部變量,獨立於Student外,固然也和建立的學生對象沒有任何關聯。之後在訪問count的時候會很麻煩,在Student類中訪問count也很麻煩。spa
指針
package static_args_methods.args; public class Static_args { public static void main(String[] args) { Student student = new Student("小范"); System.out.println(student.showFee()); // 100 Student student2 = new Student("小黃"); System.out.println(student2.showFee()); //200 // System.out.println(Student.fee); //私有屬性,沒法訪問 System.out.println(Student.count); //2 } } class Student{ private String name; //static + 訪問修飾符 + 類型 + 屬性名 static private double fee; //學費 static Blackboard bb; //黑板 //訪問修飾符 + static + 類型 + 屬性名 (推薦) public static int count; //人數 public Student(String name) { super(); this.name = name; fee += 100; //每一個學生交100學費 count += 1; } public double showFee(){ return fee; } } class Blackboard{ }
由此案例,引出類變量/靜態變量的概念及使用。對象
類變量也叫靜態變量/靜態屬性,是該類的全部對象共享的變量,任何一個該類的對象去訪問它時,取到的都是相同的值,一樣任何一個該類的對象去修改它時,修改的也是同一個變量。blog
訪問修飾符 static 數據類型 變量名; [推薦] 生命週期
static 訪問修飾符 數據類型 變量名; 虛擬機
類名.類變量名 [推薦]it
或者 對象名.類變量名 【靜態變量的訪問修飾符的訪問權限和範圍 和 普通屬性是同樣的。】
當須要一個類的全部對象均可以共用一個屬性時,就能夠將此屬性設置爲靜態屬性。例如,Student中的count屬性。
被靜態static修飾過的屬性,在類加載時就會被生成,而後初始化。
建議使用「類名.屬性名」 的方式訪問靜態屬性,由於靜態屬性(類變量)的生命週期是隨類的加載開始,隨着類消亡而銷燬。在類加載的時候,並無對象被建立,此時也能夠使用類變量。
類變量是全部對象共享使用的,而普通變量是每一個對象都獨有的。
類變量的使用,訪問權限也是由訪問修飾符修飾的。例如:Student 的類變量 count 是 private 修飾的,那麼在 Static_args 類中也不能經過 Student.count 來訪問。
類方法也叫靜態方法 。
形式以下:
訪問修飾符 static 數據返回類型 方法名() { } 【推薦】
static 訪問修飾符 數據返回類型 方法名() { }
類方法的調用:
使用方式: 類名.類方法名 或者 對象名.類方法名 【前提是 知足訪問修飾符的訪問權限和範圍】
類方法與普通方法都是在類加載時就加載了,將其結構信息放在方法區中。
類方法中沒有this關鍵字,也不能使用super關鍵字。由於類方法在類加載時就能夠調用,此時尚未對象被生成。而this與super都是表明對象的關鍵字。
類方法/靜態方法 只能訪問靜態屬性或者調用其餘靜態方法,不能夠使用成員屬性與成員方法。由於在類方法被加載時,成員屬性與成員方法都尚未被加載出來,不能使用。【前提是 知足訪問修飾符的訪問權限和範圍】
而在成員方法(普通方法)中能夠使用全部的靜態方法與靜態屬性。【前提是 知足訪問修飾符的訪問權限和範圍】
但不要誤理解爲,靜態方法中使用的任何屬性或方法都必須是靜態的。也能夠在靜態方法中聲明普通屬性來使用。
public class StaticMethodDetail { public static void main(String[] args) { // TODO Auto-generated method stub //類方法能夠經過類名調用,也能夠經過對象名調用 new DD().hi(); DD.hi(); } } class EE { public String name = "EE"; } class DD extends EE { /* * 類方法和普通方法都是隨着類的加載而加載,將結構信息存儲在方法區 :類方法中無this的參數,普通方法中隱含着this的參數 * 類方法中,不能使用this ,普通方法能夠使用this */ private int num = 200; private static String name = "老王"; public static void hi() { //System.out.println(this.num); } //類方法中不容許使用和對象有關的關鍵字,好比this和super public static void ok() { //System.out.println(this.num); //System.out.println(super.name); } //類方法(靜態方法)中 只能訪問 靜態變量 或靜態方法 public void m1() { } public static void hello() { ok(); //m1(); System.out.println(name); } //普通成員方法(非靜態方法),既能夠訪問 普通變量(方法),也能夠訪問靜態變量(方法) public void m2() { ok(); m1(); System.out.println(name); System.out.println(num); } }
package static_args_methods.methods; public class Static_methods { public static void main(String[] args) { Person person = new Person("小黃", 2000); Person person2 = new Person("小范", 2500); //能夠使用類名調用,也能夠使用對象調用 System.out.println(Person.show()); //建議 System.out.println(person2.show()); } } class Person{ private String name; private double salary; //工資 private static double totalSalary; //總工資 public Person(String name, double salary) { super(); this.name = name; this.salary = salary; sumSalary(salary); } //靜態方法 public static void sumSalary(double salary) { totalSalary += salary; } //返回總工資(靜態方法裏只能使用靜態屬性與方法) public static double show() { // salary = 100; //Cannot make a static reference to the non-static field salary // this.totalSalary = 100; //在靜態方法中沒有this指針,也不能夠使用super return Person.totalSalary; } }
因爲java虛擬機須要調用類的main()方法,因此該方法的訪問權限必須是public,又由於java虛擬機在執行main()方法時沒必要建立對象,因此該方法必須是static的,該方法接收一個String類型的數組參數,該數組中保存執行java命令時傳遞給所運行的類的參數。
public class TestMain { private String name = "jack"; private static int num = 600; //1.main方法時JVM調用,所以 public static //2. String[] args 是運行程序時,能夠輸入的 //3. 好比 java TestMain tom jack smith public static void main(String[] args) { for(int i= 0 ; i < args.length;i++) { System.out.println(args[i]); } //m1(); m2(); System.out.println(num); //若是咱們就是要再 main調用非靜態的成員,須要先建立對象,再調用.. TestMain tm = new TestMain(); tm.m1(); } public void m1() { } public static void m2() { } }