static和final关键字

static final Java 中最常用的关键字,本文介绍它们的所有用法以及含义。
 
static 通常用来修饰类的成员变量和类的方法,它可以用在以下场合:
 
1.修饰类的成员变量:意味着这个成员变量作为整个类而不是类的某个特定对象而存在,可以通过类名直接引用它们。一个static成员变量对每个类来说都只有一份存储空间,而非static成员变量则是对每个对象有一份存储空间。
2.修饰方法:static方法可以通过类名直接访问。
3.静态导入:静态导入static成员变量和static方法。
4.静态程序块:通常用来做一些初始化,static{}。
5.修饰成员类型:如修饰嵌套类(nested class),嵌套类和普通的内部类的区别就在于static的修饰。普通的内部类不能包含static数据和static属性,也不能包含嵌套类,但是嵌套类可以包含所有东西。注意static不能用来修饰最顶层的类。
 
下面的代码显示了static 的可用之处和不可用之处:
// 导入静态成员,不常用
import static java.util.Calendar. AM ;
import  java.util.HashMap;
public   class StaticTest {
    // 静态成员变量,它只存有一份
    private static   int i = 123;
    private int j = 0;
    private static HashMap map = new HashMap();
   
    // 静态程序块,用来做一些初始化动作
    static {
        map .put( "userid" , "admin" );
    }
    public void printI() {
        System. out .println( "i=" + i );
    }
    // 静态方法,
    public static void s() {
        int m = 0; // 可以定义非静态变量
        static int n = 0; // 错误代码,不能定义静态变量
        System. out .println( i ); // 可以使用静态的成员变量
        System. out .println( j ); // 错误代码,不能使用非静态的成员变量
    }
    public static void main(String[] args) {
        // 直接通过类引用静态成员变量和方法
        StaticTest.s();
        StaticTest. i ++;
        //test1 test2 打印出来的 i 值一样,因为它只有一份
        StaticTest test1 = new StaticTest();
        StaticTest test2 = new StaticTest();
        test1.printI(); //i=124
        test2.printI(); //i=124
    }
}
 
下面的代码显示了static 修饰嵌套类:
public   class StaticTest2 {
    // 普通内部类
    class InnerClass {
        static int i = 0; // 错误代码,普通内部类不能使用静态成员变量
        static final int j = 0; // 正确代码,常量
    }
    // 嵌套类,与普通内部类的区别在于多了 static 的修饰
    static class NestedClass {
        static int i = 0; // 正确代码
    }
}
 

final关键字通常表示一个东西是不能改变的,它可以修饰的元素有:

1.修饰数据:通常用来定义常量。对于基本类型,final使数值恒定不变,而对于对象引用,final使引用恒定不变,一旦引用被初始化指向一个对象,就无法把它改为指向另一个对象,然而,对象其本身是可以被修改的。

2.修饰参数:和修饰数据一样。

3.修饰方法:通常用来防止方法被子类覆盖(overriden),一个类中的所有private方法都隐含是final的,因为它无法被子类读取,也就不会被覆盖。另外,编译器针对final方法的调用都采用内嵌(inline)调用,可提高效率,但不是final的主要用途。

4.修饰类:表明该类(class)不能被继承。在final类里,所有的方法都被隐含的指定为final的,因为永远不存在子类,也就不存在子类覆盖一说。final类的字段可以根据个人的意愿选择是或不是final,不论类是否定义为final,相同的规则都适用于final字段。

平日在编程中用的最多的应该是使用final修饰数据,尤其是定义常量。

 
下面的代码显示了final 对各种元素的修饰:
// 修饰类,类不能被继承
public final class FinalTest {
    // 修饰数据, i 不能被再次赋值
    private final int i = 0;
 
    // 修饰方法,该方法不能被子类覆盖
    public final void f(String s) {
        System. out .println( "FinalTest.f" );
    }
    // 修饰参数, j 不能被重新赋值
    public void g( final int j) {
        j = 1; // 这条语句是错误的
    }
}
 
下面的代码显示了父类不能覆盖子类的final 方法:
public   class FinalChild extends Final {
    // 这个方法是错误的,它不能覆盖父类的 final 方法
    public void f(){};
    // 这个方法正确,重载
    public void f(String s){}
}
class Final {
    public final void f() {}
}
 
对于对象引用的修饰容易让人迷惑,看下面的程序:
final int i = 0;
i = 1; // 错误的代码,不能重新赋值
final StringBuffer s = new StringBuffer( "Java" );
s.append( "World!" ); // 正确代码,可以改变对象内容
s = new StringBuffer( "Hello" ); // 错误的代码,不能给引用重新赋值,它不能指向别的对象
 
注意代码注释,对整型i 的修饰很好理解,给了i 初值后,不能再给它其它值。而对于对象引用s ,虽然用了final 修饰并赋了初值,但依然可以使用s 来操纵对象,只不过,不能再将s 指向其它对象。
 
不要以为在定义final 数据成员时必须指定初值,也不要以为它只能给一个常数值,它还可以是一个表达式,如下面的代码是成立的:
final int j;
j = 2 * 3;
像上面这种未指定初值的声明final数据成员通常称为空白final。
 
对于类的成员变量,有无final修饰存在一点区别,对于没有final修饰的成员变量,它们都有一个默认的初值(如整型数据为0),而对于final修饰的成员变量,必须确保它被初始化。看下面的程序:
public class TestFinal {   
    private int i ; // 默认值为 0 。如果是 private final int i; 程序就会报错
    public void print() {
        System. out .println( i );
    }
}
 
如果使用final修饰i,程序就会出错,因为它未被初始化。如果想用final修饰的同时又不想在声明时初始化,则 可以在构造函数中赋值。如下面的程序是正确的:
public class TestFinal {   
    private final int i ;
    public TestFinal () {
        i = 0;
    }
    public void print() {
        System. out .println( i );
    }
}
 

一个既是static又是final的字段只占据一段不能改变的存储空间。 带有恒定初始值(即,编译时常量)的static final基本类型全用大写字母命名,并且字与字之间用下划线隔开。如java.lang.byte类里对byte类型的最小值定义:

public static final byte    MIN_VALUE = -128;
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值