final和static关键字
1、final关键字
1、含义
final在Java中是一个保留的关键字,可以声明成员变量、方法、类以及本地变量。一旦你将引用声明作final,你将不能改变这个引用了,
编译器会检查代码,如果你试图将变量再次初始化的话,编译器会报编译错误。
2、final类(final修饰类)
被final修饰的类,是不可以被继承的,这样做的目的可以保证该类不被修改,Java的一些核心的API都是final类,例如String、Integer、Math等
3、final方法(final修饰方法)
final也可以声明方法。方法前面加上final关键字,代表这个方法不可以被子类的方法重写。
如果你认为一个方法的功能已经足够完整了,子类中不需要改变的话,你可以声明此方法为final。final方法比非final方法要快,因为在编译的时候已经静态绑定了,不需要在运行时再动态绑定。
final方法的原因有二:
第一、把方法锁定,防止任何继承类修改它的意义和实现。
第二、高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。
4、final修饰实例变量(类的属性,定义在类内,但是在类内的方法之外)
final修饰实例变量时必须初始化,且不可再修改;
示例:
final修饰实例变量时必须初始化,且不可再修改代码。
5、final修饰局部变量(方法体内的变量)
final修饰局部变量时只能初始化(赋值)一次,但也可以不初始化
6、final修饰方法参数
final修饰方法参数时,是在调用方法传递参数时候初始化的
7、final关键字的好处
- final关键字提高了性能。JVM和Java应用都会缓存final变量。
- final变量可以安全的在多线程环境下进行共享,而不需要额外的同步开销。
- 使用final关键字,JVM会对方法、变量及类进行优化。
8、final关键字知识点总结
- final关键字可以用于成员变量、本地变量、方法以及类。
- final成员变量必须在声明的时候初始化或者在构造器中初始化,否则就会报编译错误。
- 你不能够对final变量再次赋值。
- 本地变量必须在声明时赋值。
- 在匿名类中所有变量都必须是final变量。
- final方法不能被重写。
- final类不能被继承。
- final关键字不同于finally关键字,后者用于异常处理。
- final关键字容易与finalize()方法搞混,后者是在Object类中定义的方法,是在垃圾回收之前被JVM调用的方法。
- 接口中声明的所有变量本身是final的。
- final和abstract这两个关键字是反相关的,final类就不可能是abstract的。
- final方法在编译阶段绑定,称为静态绑定(static binding)。
- 没有在声明时初始化final变量的称为空白final变量(blank final variable),它们必须在构造器中初始化,或者调用this()初始化。不这么做的话,编译器会报错“final变量(变量名)需要进行初始化”。
- 将类、方法、变量声明为final能够提高性能,这样JVM就有机会进行估计,然后优化。
- 按照Java代码惯例,final变量就是常量,而且通常常量名要大写:
private
final
int
COUNT =
10
;
16.对于集合对象声明为final指的是引用不能被更改,但是你可以向其中增加,删除或者改变内容。譬如:
private
final
List Loans =
new
ArrayList();
list.add(“home loan”);
//valid
list.add(
"personal loan"
);
//valid
loans =
new
Vector();
//not valid
2、static关键字
1、概念
static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念。
被static修饰的成员变量和成员方法独立于该类的任何对象,也就是说,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就能根据类
名在运行时数据区的方法区内定找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。
用public修饰的static成员变量和成员方法本质是全局变量和全局方法,当声明它类的对象时,不生成static变量的副本,而是类的所有实例共享同一个static变量。
static变量前可以有private修饰,表示这个变量可以在类的静态代码块中,或者类的其他静态成员方法中使用,但是不能在其他类中通过类名来直接引用。
类名.静态方法名(参数列表...)
类名.静态变量名
2、修饰成员变量
static最常用的功能就是修饰类的属性和方法,让他们成为类的成员属性和方法,我们通常将用static修饰的成员称为类成员或者静态成员:
Java类提供了两种类型的变量:
用static关键字修饰的静态变量和不用static关键字修饰的实例变量。静态变量属于类,在内存中只有一个复制,只要静态变量所在的类被加载,这个静态变量就会被分配空间,
因此就可以被使用了。对静态变量的引用有两种方式,分别是“类.静态变量"和”对象.静态变量"
实例变量属于对象,只有对象被创建后,实例变量才会被分配内存空间,才能被使用,它在内存中存在多个复制,只有用“对象.实例变量”的方式来引用。
3、static成员方法
Java中提供了static方法和非static方法。static方法是类的方法,不需要创建对象就可以被调用,而非static方法是对象的方法,只有对象被创建出来后才可以被使用
static方法中不能使用this和super关键字,不能调用非static方法,只能访问所属类的静态成员变量和成员方法,因为当static方法被调用时,这个类的对象可能还没被
创建,即使已经被创建了,也无法确定调用哪个对象的方法。同理,static方法也不能访问非static类型的变量。
1 public class PrintHelper {
2
3 public static void print(Object o){
4 System.out.println(o);
5 }
6
7 public static void main(String[] args) {
8 PrintHelper.print("Hello world");
9 }
10 }
4、static代码块
static代码块在类中是独立于成员变量和成员函数的代码块的。注意:这些static代码块只会被执行一次
1 class Book{
2 public Book(String msg) {
3 System.out.println(msg);
4 }
5 }
6
7 public class Person {
8
9 Book book1 = new Book("book1成员变量初始化");
10 static Book book2;
11
12 static {
13 book2 = new Book("static成员book2成员变量初始化");
14 book4 = new Book("static成员book4成员变量初始化");
15 }
16
17 public Person(String msg) {
18 System.out.println(msg);
19 }
20
21 Book book3 = new Book("book3成员变量初始化");
22 static Book book4;
23
24 public static void funStatic() {
25 System.out.println("static修饰的funStatic方法");
26 }
27
28 public static void main(String[] args) {
29 Person.funStatic();
30 System.out.println("****************");
31 Person p1 = new Person("p1初始化");
32 }
33 /**Output
34 * static成员book2成员变量初始化
35 * static成员book4成员变量初始化
36 * static修饰的funStatic方法
37 * ***************
38 * book1成员变量初始化
39 * book3成员变量初始化
40 * p1初始化
41 *///~
5、静态导包
1 /* PrintHelper.java文件 */
2 package com.dotgua.study;
3
4 public class PrintHelper {
5
6 public static void print(Object o){
7 System.out.println(o);
8 }
9 }
1 /* App.java文件 */
2
3 import static com.dotgua.study.PrintHelper.*;
4
5 public class App
6 {
7 public static void main( String[] args )
8 {
9 print("Hello World!");
10 }
11 /**Output
12 * Hello World!
13 *///~
14 }
上面的代码来自于两个java文件,其中的PrintHelper很简单,包含了一个用于打印的static方法。而在App.java文件中,我们首先将PrintHelper类导入,这里在导入时,我们使用了static关键字,而且在引入类的最后还加上了“.*”,它的作用就是将PrintHelper类中的所有类方法直接导入。不同于非static导入,采用static导入包后,在不与当前类的方法名冲突的情况下,无需使用“类名.方法名”的方法去调用类方法了,直接可以采用"方法名"去调用类方法,就好像是该类自己的方法一样使用即可。
6、总结
static是java中非常重要的一个关键字,而且它的用法也很丰富,主要有四种用法:
- 用来修饰成员变量,将其变为类的成员,从而实现所有对象对于该成员的共享;
- 用来修饰成员方法,将其变为类方法,可以直接使用“类名.方法名”的方式调用,常用于工具类;
- 静态块用法,将多个类成员放在一起初始化,使得程序更加规整,其中理解对象的初始化过程非常关键;
- 静态导包用法,将类的方法直接导入到当前类中,从而直接使用“方法名”即可调用类方法,更加方便。
3、static与final结合使用表示的意思: