目录
- 1.static:静态的
- 2.static可以用来修饰:属性、方法、代码块、内部类
- 3.使用static修饰属性:静态变量(或类变量)
- 4.使用static修饰方法:静态方法
- 4.1 Java中静态方法能否被重写
- 5.static注意点:
- 6.开发中的使用:
- 练习题:
1.static:静态的
2.static可以用来修饰:属性、方法、代码块、内部类
3.使用static修饰属性:静态变量(或类变量)
3.1 属性,按照是否使用static修饰,有分为:静态属性 vs 非静态属性(实例变量)
实例变量:我们创建了类的多个对象,每个对象都独立的拥有一套类中的非静态属性。当修改其中一个对象的非静态属性时,不会导致其他对象中同样的属性值的修改。
静态变量:我们创建了类的多个对象,多个对象共享一个静态变量,当通过某一个对象修改静态变量时,会导致其他对象调用此静态变量时,是修改过的。
3.2 static修饰属性的其他说明:
① 静态变量随着类的加载而加载。可以通过“类.静态变量”的方式进行调用。
② 静态变量的加载要早于对象的创建。
③ 由于类只会加载一次,则静态变量在内存中也会存在一份:存在方法区的静态域中。
④ 类可以直接调用类变量,但是不能调用实例变量。
对象可以调用类变量,也可以调用实例变量。
3.3 静态属性的举例:System.out; Math.PI等
代码演示静态变量:
package com.fan.domain;
public class StaticTest {
public static void main(String[] args) {
Chinese.nation = "中国";
Chinese c1 = new Chinese();
c1.name = "姚明";
c1.age = 40;
c1.nation = "CHN";
Chinese c2 = new Chinese();
c2.name = "马龙";
c2.age = 30;
c2.nation = "CHINA";
System.out.println(c1.nation);
//编译不通过
//Chinese.name = "张继科";
}
}
//中国人
class Chinese{
static String nation;
String name;
int age;
}
类变量和实例变量的内存解析图:
总结static修饰的属性:
随着类的加载而加载;早于对象的创建;只要权限允许,可以通过“对象.属性”的方式进行调用;存在于方法区的静态域。
4.使用static修饰方法:静态方法
操作静态属性的方法,通常设置为static的方法
① 随着类的加载而加载,可以通过“类.静态方法”的方式进行调用
② 类可以直接调用类方法(静态方法),但是不能调用实例方法(非静态方法)。
对象可以调用静态方法,也可以调用非静态方法。
③ 静态方法中,只能调用静态的方法或属性
非静态方法中,既可以调用非静态的方法或属性,也可以调用静态的方法或属性。
④ 在Java中静态方法可以被继承,但是不能被覆盖,即不能重写。
4.1 Java中静态方法能否被重写
代码演示静态方法可以被继承,但是不能被覆盖:
public class Test {
public static void main(String[] args) {
/**
* 结论:
* 静态方法可以被继承,但是不能被覆盖,即不能重写。
* */
Son.staticMethod(); // 运行结果:Father staticMethod
}
}
class Father {
public static void staticMethod() {
System.out.println("Father staticMethod");
}
}
class Son extends Father {
}
代码二:
public class Test {
public static void main(String[] args) {
Father.staticMethod(); // 运行结果:Father staticMethod
/**
* 结论:
* 类执行了自己申明的静态方法。
* 该子类实际上只是将父类中的同名静态方法进行了隐藏,而非重写。
* */
Son.staticMethod(); // 运行结果:Son staticMethod
Father father = new Son();
/**
* 结论:
* 父类引用指向子类对象时,只会调用父类的静态方法。
* 父类和子类中含有的其实是两个没有关系的方法,它们的行为也并不具有多态性。
* */
father.staticMethod(); // 运行结果:Father staticMethod
}
}
class Father {
public static void staticMethod() {
System.out.println("Father staticMethod");
}
}
class Son extends Father {
public static void staticMethod() {
System.out.println("Son staticMethod");
}
}
总结:
1.在Java中静态方法可以被继承,但是不能被覆盖,即不能重写。
2.如果子类中也含有一个返回类型、方法名、参数列表均与之相同的静态方法,那么该子类实际上只是将父类中的该同名方法进行了隐藏,而非重写。
3.父类引用指向子类对象时,只会调用父类的静态方法。所以,它们的行为也并不具有多态性。
5.static注意点:
5.1 在静态的方法内,不能使用this关键字和super关键字
5.2 关于静态属性和静态方法的使用,大家都从生命周期的角度去理解。
5.3 在调用静态属性的时候,省略了类. 关键字。
总结:静态结构是和类的生命周期同步的。而非静态的结构是和对象的生命周期同步的。晚一点出生的可以调用早一点出生的。而早出生的不能调用晚出生的,因为它还没有呢。比如你可以向你老爸去借钱,但是你不能向你孩子去借钱(可能还没出生呢)。
6.开发中的使用:
开发中,如何确定一个属性是否要生命为static的?
属性是可以被多个对象所共享的。不会随着对象的不同而不同的。
类中的常量也常常被声明为static
开发中,如何确定一个方法是否要生命为static的?
操作静态属性的方法,通常设置为static的方法。
工具类中的方法,习惯上生命为static的,比如:Math,Arrays,Collections的。(为了避免造对象再去调用方法的麻烦,使用静态方法方便调用)
代码理解:
package com.fan.domain;
public class CircleTest {
public static void main(String[] args) {
Circle c1 = new Circle();
Circle c2 = new Circle();
Circle c3 = new Circle(3);
System.out.println("c1的id:"+ c1.getId());
System.out.println("c2的id:"+ c2.getId());
System.out.println("c3的id:"+ c3.getId());
System.out.println("创建的圆的个数是"+Circle.getTotal());
}
}
class Circle {
private double radius;//圆的半径
private int id;
public Circle(){
id = init++;
total++;
}
public Circle(double radius){
this();//这一行不加的话,就不会自动累加
/* id = init++;
total++;*/
this.radius = radius;
}
private static int total;//记录圆的个数
private static int init = 1001;//多个对象共享static声明的属性
public double findArea(){
return 3.14 * radius * radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public static int getTotal() {
return total;
}
public static void setTotal(int total) {
Circle.total = total;
}
public static int getInit() {
return init;
}
public static void setInit(int init) {
Circle.init = init;
}
}
练习题:
注意:静态的属性不要放构造器中初始化。