关于static关键字的用法,主要是用来修饰方法或则成员变量。
static修饰成员变量时:该成员变量就会成为一个共享的数据。(一般使用是static修饰成员变量是会加private)
静态成员变量的访问方式:
- 使用对象名访问:对象名.属性名
- 使用类名访问:类名.属性名
class Demo{
//定义一个静态成员变量PI
public static double PI = 3.14;
}
public class Main{
public static void main(String[] args) {
Demo d = new Demo();
System.out.println(d.PI);
System.out.println(Demo.PI);
}
}
静态的成员变量与非静态的成员变量的区别:
1.作用上的区别:
1.静态的成员变量的作用是共享一个数据给所有的对象使用。
2.非静态的成员变量的作用是描述一类事物的公共属性。2.数量与存储位置的区别:
1.静态成员变量是存储在方法区 内存中,而且只会存在一份数据。
2.非静态成员变量是存储在堆内存中,有n个对象就有n份数据。3.生命周期的区别:
1.静态的成员变量数据是随着类的加载而存在,随着类的消失而消失。
2.非静态的成员变量数据是随着对象的创建而存在,随着对象被垃圾回收器回收而消失。
static 修饰方法时静态方法的访问方式:
- 使用对象名访问:对象名.方法名
- 使用类名访问:类名.方法名
class Demo{
//定义一个静态成员变量PI
public static double PI = 3.14;
//定义静态方法
public static void laugh(){
System.out.println("哈哈哈!!!");
}
}
public class Main{
public static void main(String[] args) {
Demo d = new Demo();
d.laugh();
Demo.laugh();
}
}
推荐使用类名直接访问静态成员。
静态方法要注意的事项:
1.静态方法可以使用类名也可以使用对象来调用,而非静态方法只能使用对象来调用。
2.静态方法可以直接访问静态的成员,但是不能直接访问非静态的成员。
原因:静态方法是可以使用类名进行访问的,而这个时候可能还不存在对象,而非静态的成员数据是随着对象的创建而存在的
3.非静态方法是可以直接访问静态与非静态的成员。
原因:非静态方法只能由对象调用,当对象创建成功的时候,静态数据已经存在了,而非静态的数据也随着对象的创建而存在了。
4.静态方法不能出现this或者super关键字。
原因:(因为静态方法可以直接使用类名进行访问,this关键字代表的是调用方法的对象,此时就会产生冲突))
class Demo1{
//静态成员变量
public static double PI = 3.14;
//非静态成员变量
public int age = 10;
/*
2.静态方法可以直接访问静态的成员,但是不能直接访问非静态的成员。
原因:静态方法是可以使用类名进行访问的,而这个时候可能还不存在对象,而非静态的成员数据是随着对象的创建而存在的
4.静态方法不能出现this或者super关键字。
原因:(因为静态方法可以直接使用类名进行访问,this关键字代表的是调用方法的对象,此时就会产生冲突))*/
//静态方法
public static void laugh(){
// this.age; //报错:'com.demo_03.Demo1.this' cannot be referenced from a static context
// super.clone(); //报错:'com.demo_03.Demo1.super' cannot be referenced from a static context
System.out.println("哈哈哈!!!");
System.out.println("PI: "+PI);
// System.out.println("age:"+age); //报错:Non-static field 'age' cannot be referenced from a static context
}
/* 3.非静态方法是可以直接访问静态与非静态的成员。
原因:非静态方法只能由对象调用,当对象创建成功的时候,静态数据已经存在了,而非静态的数据也随着对象的创建而存在了。*/
//非静态方法
public void show(){
System.out.println("PI: "+PI);
System.out.println("age:"+age);
}
}
public class Main {
public static void main(String[] args) {
Demo1 d = new Demo1();
/* 1.静态方法可以使用类名也可以使用对象来调用,而非静态方法只能使用对象来调用。*/
//使用对象名和类名访问静态方法
d.laugh();
Demo1.laugh();
//使用对象名和类名访问非静态方法
d.show();
// Demo1.show(); //报错:Non-static method 'show()' cannot be referenced from a static context
}
}
static什么时候修饰一个方法?
如果一个方法没有直接访问到非静态的成员时,那么就可以使用static修饰,常用于定义工具类
案例:自定义工具类MyRandom生成随机数
Java给的Random类的 nextInt( n ) 方法产生的随机数范围只能在 0 到 n-1 之间,而我需要得到 一个范围的数据 比如 10 - 20之间的数,包含10和20,这时 nextInt( n ) 方法就无法实现,所以需要自定义一个类和方法去实现该功能
/*
定义工具类MyRandom ,生成一个方法randomInt,获得两个参数min 、max,生成的随机数包含min 、max
*/
class MyRandom {
//为了让别人能直接使用Random对象,将这个成员变量设计为public static final
public static final Random r = new Random();
//自定义一个方法,为了让别人使用这个方法更方便,我们将方法设计为 static
public static int randomInt(int min,int max){
//进行参数的逻辑校验,
if(max<min||min<0){
System.out.println("参数有问题!");
return -1;
}
return r.nextInt(max-min+1)+min;
}
}
public class Main {
public static void main(String[] args) {
//通过类名调用方法randomInt()并传递两个参数(min,max)获取 min 到 max 之间的随机数,包含 min 、max
int num = MyRandom.randomInt(12,40);
int num2 = MyRandom.randomInt(-5,40);
System.out.println(num);
System.out.println(num2);
}
}