Day35--static关键字详解
Day35--static关键字详解
示例:
package com.liu.oop.demo07;
//static
public class Student {
private static int age; //静态的变量
private double score; //非静态的变量
public static void main(String[] args) {
Student s1 = new Student();
System.out.println(s1.age); //通过对象调用方法
System.out.println(Student.age);//通过类调用方法
System.out.println(s1.score);
System.out.println(Student.score);//报错
}
}
上面的代码,为什么对方法age,通过对象调用和通过类调用都可以,而对方法score,不能通过类调用?
详细解释;
一、关于静态变量
在 Java 中,静态变量(用static关键字修饰)的,既可以通过类名Student
来访问它(如Student.age
),也可以通过创建的对象来访问(如s1.age
,这里s1
是Student
类的一个实例对象)
二、关于非静态变量
非静态变量(没有用static
关键字修饰的变量)必须通过创建对象来访问。
再比如:创建了非静态方法run和静态方法go,如何在下面的代码main方法中调用他们?
package com.liu.oop.demo07;
//static
public class Student {
private static int age; //静态的变量
private double score; //非静态的变量
public void run(){}
public static void go(){}
public static void main(String[] args) {
}
}
实际方法:
package com.liu.oop.demo07;
//static
public class Student {
private static int age; //静态的变量
private double score; //非静态的变量
public void run(){}
public static void go(){}
public static void main(String[] args) {
new Student().run(); //调用非静态方法
Student.go(); //调用静态方法
//go(); 在同一个类里面,也可以
}
}
与此同时,我们发现了一个有趣的事情:
非静态方法可以调用静态方法,但是静态方法不能调用非静态方法
public void run(){
go();//可以
}
public static void go(){
run();//报错
}
在类里面,有代码块
package com.liu.oop.demo07;
public class Person {
{
//代码块(匿名代码块)
}
static {
//静态代码块
}
}
我们可以借此了解代码块的相关信息
猜一猜,下面的代码输出结果是什么?
package com.liu.oop.demo07;
public class Person {
{
System.out.println("匿名代码块");
//代码块(匿名代码块)
}
static {
System.out.println("静态代码块");
//静态代码块
}
public Person() {
System.out.println("构造方法");
}
public static void main(String[] args) {
new Person();
}
}
代码输出结果是:
静态代码块
匿名代码块
构造方法
代码第一次执行,按照先后顺序来看,
首先执行的是:静态代码块
然后执行的是:匿名代码块
最后执行的是:构造器
也就是说,在创建对象的时候,先执行静态代码块,再执行匿名代码块,最后执行构造器
那么,再执行一次,结果会有变化吗?
package com.liu.oop.demo07;
public class Person {
//2
{
System.out.println("匿名代码块");
//代码块(匿名代码块)
}
//1
static {
System.out.println("静态代码块");
//静态代码块
}
//3
public Person() {
System.out.println("构造方法");
}
public static void main(String[] args) {
Person person1 = new Person();
System.out.println("=========================================");
Person person2 = new Person();
}
}
输出结果:
静态代码块
匿名代码块
构造方法
=========================================
匿名代码块
构造方法
可见,静态代码块只执行一次
匿名代码块可以用来赋初始值
再一个例子:
想生成随机数,我们可以这样:
package com.liu.oop.demo07;
public class Test {
public static void main(String[] args) {
System.out.println(Math.random());
}
}
但是,能不能直接System.out.println(random()); 不用Math?
可以!!!
导入
package com.liu.oop.demo07;
//静态导入包
import static java.lang.Math.random;
public class Test {
public static void main(String[] args) {
System.out.println(random());
}
}
拓展:
如果类是被final修饰的,他没有子类
假如Person是被final修饰的,想让Test作它的子类,不行
package com.liu.oop.demo07;
public final class Person
public class Test extends Person{ //报错