一.static关键字

1.基本概念

static表示“全局”或者“静态”的意思。

static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念。

被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。

为什么需要static关键字?可以通过以下两种情形进行思考

情形一:只想为某特定域分配单一存储空间,而不去考虑究竟要创建多少对象,甚至根本就不创建任何对象。
情形二:希望某个方法不与包含它的类的任何对象关联在一起。也就是说,即使没有创建对象,也可以调用这个方法。

使用注意:

静态方法只能访问类的静态成员,但是非静态方法却可以访问类中的所有成员(非静态成员需要创立类的实例来使用它的非静态成员)
静态方法中不可以写this,super关键字
主函数是静态的
类的构造函数默认是静态的,只是没有显示的加static

2.使用分类

2.1静态变量

被static修饰后的成员变量具备以下特点

  • 随着类的加载而加载就在方法区中的静态区开辟内存,优先于非静态成员变量存在。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象
  • 优先于对象存在
  • 可以直接被类名调用
  • 被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。

静态成员变量和非静态成员变量的对比

  1. 生命周期
    非静态成员变量是随着对象的创建而出现,随着对象的被垃圾回收而消失,静态成员是随着类的加载而出现,随着程序的运行结束才消失。这也是静态成员的弊端,生命周期太长。
  2. 存储位置
    非静态成员是随着对象的创建在堆(或栈)中开辟内存。
    静态成员存储的是所有对象共享的数据。
  3. 存放的数据的特点
    非静态成员存储的是每个对象特有的数据,非静态变量可以在内存中有多个拷贝,互不影响(灵活)。
    静态成员存储的是所有对象共享的数据,静态变量在内存中只有一个拷贝(节省内存),JVM只为静态分配一次内存,在加载类的过程中完成静态变量的内存分配。
  4. 访问方式
    非静态成员只能通过对象访问它
    静态成员既可以通过对象,也可以通过类直接访问

2.2静态方法

静态方法可以直接通过类名调用,任何的实例也都可以调用,因此静态方法中不能用this和super关键字,不能直接访问所属类的实例变量和实例方法(就是不带static的成员变量和成员成员方法),只能访问所属类的静态成员变量和成员方法。因为实例成员与特定的对象关联!这个需要去理解,想明白其中的道理,不是记忆!!!

因为static方法独立于任何实例,因此static方法必须被实现,而不能是抽象的abstract。

2.3静态代码块

static代码块也叫静态代码块,是在类中独立于类成员的static语句块,可以有多个,位置可以随便放,它不在任何的方法体内,JVM加载类时会执行这些静态的代码块,如果static代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次。

2.4静态类

static关键字只是说明其在创建对象时不依赖于外部类对象的存在,并不是说这个类本身是静态的。–《java开发手册》

如果一个类要被声明为static的,只有一种情况,就是静态内部类。如果在外部类声明为static,程序会编译都不会过。在一番调查后个人总结出了3点关于内部类和静态内部类(俗称:内嵌类)

  1. 静态内部类跟静态方法一样,只能访问静态的成员变量和方法,不能访问非静态的方法和属性,但是普通内部类可以访问任意外部类的成员变量和方法
  2. 静态内部类可以声明普通成员变量和方法,而普通内部类不能声明static成员变量和方法。
  3. 静态内部类可以单独初始化:

静态内部类的应用场景:
静态内部类使用场景一般是当外部类需要使用内部类,而内部类无需外部类资源,并且内部类可以单独创建的时候会考虑采用静态内部类的设计,

静态内部类和非静态内部类(如匿名内部类)的区别:
1. 静态内部类就是个独立的类。非静态的才是真正的内部类,对其外部类有个引用。
2. static关键字只是说明其在创建对象时不依赖于外部类对象的存在,并不是说这个类本身是静态的。
3. 非晶态的内部类对象隐式地在外部类中保存了一个引用,指向创建它的外部类对象。
4. 可以创建静态的成员方法与成员变 量(静态内部类可以创建静态的成员而非静态的内部类不可以)
5. 对于访问外部类的成员的限制(静态内部类只可以访问外部类中的静态成员变量与成员方法,而非静态的内部类即可以访问静态的也可以访问非静态的外部类成员方法与成员变量)

二.final关键字

基本概念

final:最终的,修饰类、方法、成员变量、局部变量
被final修饰的类,不能有子类
被final修饰的方法,不能被子类重写
final成员变量表示常量,只能被赋值一次,赋值后值不再改变。

其他都好理解,这里重点说下

final变量(常量):

用final修饰的成员变量表示常量,值一旦给定就无法改变!
final修饰的变量有三种:静态变量、实例变量和局部变量,分别表示三种类型的常量。
从下面的例子中可以看出,一旦给final变量初值后,值就不能再改变了。
另外,final变量定义的时候,可以先声明,而不给初值,这中变量也称为final空白,无论什么情况,编译器都确保空白final在使用之前必须被初始化。但是,final空白在final关键字final的使用上提供了更大的灵活性,为此,一个类中的final数据成员就可以实现依对象而有所不同,却有保持其恒定不变的特征。

final参数:

当函数参数为final类型时,你可以读取使用该参数,但是无法改变该参数的值。

使用分类

三.static和final一起使用

对于static final修饰的变量,表示一旦赋值就不可修改,并且可通过类名直接访问
对于static final修饰的方法,表示该方法不可覆盖,并且可通过类名直接调用
对于static final修饰的引用类型对象,特别是容器类型(如ArrayList、HashMap),不可以改变容器对象本身(即不能改变将其引用指向其他对象),但可以修改容器中存放的对象。

四.参考资料

Java关键字final、static使用总结
http://lavasoft.blog.51cto.com/62575/18771

java中static关键字的理解
http://blog.csdn.net/caohaicheng/article/details/14002735

为什么Java内部类要设计成静态和非静态两种?
https://www.zhihu.com/question/28197253

JAVA 内部静态类–解析静态内部类的使用目的与限制
http://blog.csdn.net/vange/article/details/5407625

建议38: 使用静态内部类提高封装性
http://book.51cto.com/art/201202/317517.htm

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐