1. 介绍
在Java中,static是一个关键字,用于修饰类、方法和变量。使用static关键字声明的成员属于类级别,不需要实例化对象就可以访问和使用。在类定义中使用static关键字声明的变量可以作为常量使用。
2. 为什么设计 static 关键字
提出问题的主要目的就是让大家思考解决之道,从而引出我们要讲的知识点。
说有一群小孩在玩堆雪人,不定时有新的小孩加入,请问如何之道现在共有多少人在玩,编写程序解决问题。
- 先使用之前学过的技术解决
- 思路: 在main方法中定义一个变量count
- 当有一个小孩加入游戏后, count++, count就记录了有多少小孩, 如果想知道有多少人在玩游戏, 打印count值即可
public class ChildrenGame {
public static void main(String[] args) {
int count = 0;
Chlind c1 = new Chlind("小明");
count++;
c1.join();
Chlind c2 = new Chlind("小红");
count++;
c2.join();
System.out.println("现在共有 "+count+ "个小朋友玩堆雪人") ;
}
}
class Chlind{
private String name;
public Chlind(String name) {
this.name = name;
}
public void join(){
System.out.println(this.name+" 参加游戏");
}
}
- 问题分析:
count 是一个独立的变量, 没有使用到面向对象
如果以后访问count很麻烦,比如问一个小朋友现在有多少人, 他就不知道
- 解决问题
如果设计一个 count变量,我们在创建一个小孩时,就把count +++ 并且count是对所有对象共享的就OK了,我们可以使用类变量来解决这个问题
public class ChildrenGame {
public static void main(String[] args) {
Child02 c1 = new Child02("小明");
c1.count++;
c1.join();
Child02 c2 = new Child02("小红");
c2.count++;
c2.join();
System.out.println("现在共有 "+Child02.count+ "个小朋友玩堆雪人") ;
}
}
class Child02 {
// 定义一个 静态变量(类变量) count
// 类变量的最大的特点就是可以被这个类的所有的实例共享
public static int count;
private String name;
public Child02(String name) {
this.name = name;
}
public void join(){
System.out.println(this.name+" 参加游戏");
}
}
类变量(静态/static变量)是用一个类所有对象共享的,
类变量在类加载的时候就生成了
注意 在jdk1.7 之前静态变量存储在方法区中的静态域中
3. 类变量和类方法
- 什么是类变量?
类变量也叫静态变量/静态属性,是该类的所有对象共享的变量,任何一个该类的对象去访问它时,取到的都是相同的值, 同样任何一个该类的对象去修改它时,修改的也是同一个变量。
- 定义类变量语法
访问修饰符 static 数据类型 变量名称; // 推荐这种方式
static 访问修饰符 数据类型 变量名称;
- 访问类变量
// 在满足java访问范围限制的情况下:
类名.属性名; // 推荐这种
对象名.属性名;
public class Visit {
public static void main(String[] args) {
System.out.println(Person03.public_);
System.out.println(Person03.protected_);
System.out.println(Person03.default_);
//System.out.println(Person03.privare_); // 私有静态属性, 无法访问
Person03 person = new Person03();
System.out.println(person.public_);
System.out.println(person.protected_);
System.out.println(person.default_);
//System.out.println(person.privare_); // 私有静态属性, 无法访问
}
}
class Person03{
// 定义四种静态属性,分别使用四种不同的访问修饰符修饰
public static String public_ = "publicVariable";
protected static String protected_ = "protectedVariable";
static String default_ = "defaultVariable";
private static String private_ = "privateVariable";
}
4. 类变量和类方法
- 什么时候需要使用类变量
当我们需要让某个类的所有对象都共享一个变量是,就可以考虑使用类变量,比如定义学生类, 统计学生一共交了多少钱
class Student{
String name;
static double fee;
}
- 类变量与成员变量的区别?
类变量是该类的所有对象共享的, 而成员变量是每个对象特有的
定义变量时加上
static
修饰的变量即为类变量, 否则即为普通变量/成员变量类变量可以通过
类名.类变量
或对象名.类变量
访问, 通常会使用类名.类变量
来访问,成员变量只能通过
对象名.成员变量名
来访问类变量在类加载时就已经初始化了, 也就是说即使没有实例化对象, 只要加载了类, 就可以使用类变量了
类变量的声明周期是随着类的加载开始, 随着类的销毁结束
public class Static04_visit {
public static void main(String[] args) {
System.out.println(A04.a);
}
}
class A04{
public static int a = 100;
}
5. 类方法
类方法也叫静态方法
- 定义静态方法语法
访问修饰符 static 数据类型 方法名称(形参列表){
方法体;
} // 推荐这种方式
static 访问修饰符 数据类型 方法名称(形参列表){
方法体;
}
// 如
public static void aa(){
int a = 1+1;
}
static public void bb(){
int a = 1+1;
}
- 调用静态方法
静态方法可以通过 类名.静态方法名
或 对象名.静态方法名
访问, 通常会使用 类名.静态方法名
来访问,
- 使用示例
public class Static05_method {
public static void main(String[] args) {
Stu05 s1 = new Stu05("小明");
s1.addFee(100);
Stu05 s2 = new Stu05("小明");
s2.addFee(300);
Stu05.showFee();
}
}
class Stu05{
private String name;
private static double fee;
// 使用static 修饰的方法就是静态方法,
// 静态方法可以直接实用类名访问到
public static void addFee(double fee){
Stu05.fee +=fee;
}
public static void showFee(){
System.out.println("总费用为:"+ fee);
}
public Stu05(String name) {
this.name = name;
}
}
6. 类方法使用场景
当类方法中不涉及任何和对象相关的成员, 则可以将方法设计成静态方法, 提高开发效率
比如:Math、Arrays、collections工具类中的方法
在实际开发中, 往往会用到一些通用的方法, 设计成静态方法, 这样我们不需要创建对象就可以使用他们, 比如打印一维数组, 冒泡排序完成某个计算任务等等
public class Static06_utils {
public static void main(String[] args) {
System.out.println("12 + 15 = "+ Utils.sum(12,15));
// 使用Math 工具类开平方方法
System.out.println("9 开平方结果是:" + Math.sqrt(9));
}
}
class Utils{
// 编写一个计算两个数之和的方法
public static int sum(int d1,int d2){
return d1+d2;
}
}
7. 类变量与类方法
- 类方法和普通方法都是随着类的加载而加载,将结果存储在方法区,
类方法中无this的参数
普通方法中引航者this参数
- 类方法可以通过类名调用, 也可以通过对象名调用
- 普通方法和对象有关,需要通过对象名调用,比如
对象名.方法名(实参列表)
不能通过类名调用
class Person07{
private String name;
private static String age;
public static void eat(){
System.out.println("eating . . .");
}
public static void run(){
// 静态方法中不允许使用和对象有关的关键字, 如this、super
//System.out.println(this.name);
// 静态方法中不能访问普通成员变量
//System.out.println(name);
// 静态方法中可以访问静态变量
System.out.println(age);
// 静态方法中可以访问其他的静态方法
eat();
}
}
- 静态方法中不允许使用和对象有关的关键字,比如 this、super。 普通方法可以使用这些关键字
- 在遵守访问权限的前提下,静态方法中只能访问静态变量和静态方法
- 在遵守访问权限的前提下,普通成员方法既可以访问静态方法、静态变量, 也可以访问非静态方法、非静态变量
8. main 方法
- 深入理解main 方法
解释main方法的形式,
// main 方法定义形式
public static void main(String args[]){
}
main方法是在虚拟机调用
java虚拟机需要调用类的main方法, 所以改方法必须是public 级别
java虚拟机在执行main()方法时不必创建对象, 所以该方法必须是static级别的
该方法接受String类型的数组, 该数组中保存执行java命令时所传递给所运行的类的参数,
参数传递方式 java 执行程序 参数1 参数2 参数3
- 特别提示
- 在main方法中, 我们可以直接调用main方法所在类的静态方法或静态属性
- 但是, 不能直接访问该类中的非静态成员, 必须创建该类的一个实例后, 才能通过这个对象访问非静态成员
class Main11{
public static void m1(){
System.out.println("Main11 静态方法");
}
public void m2(){
System.out.println("Main11 非静态方法");
}
// 静态变量
public static int v1 = 100;
// 非静态变量
public int v2 = 100;
public static void main(String[] args) {
// 可以直接访问静态属性
System.out.println(v1);
// 不可以直接访问非静态属性
//System.out.println(notStaticVariable);
// 可以直接访问静态方法
m1();
// 不可以直接访问非静态方法
//notStaticMethod();
// 实例化对象========================
Main11 m = new Main11();
// 实例化对象可以直接访问静态属性
System.out.println(m.v1);
// 实例化对象可以直接访问非静态属性
System.out.println(m.v2);
// 实例化对象可以直接访问静态方法
m.m1();
// 实例化对象可以直接访问非静态方法
m.m2();
}
}