Java学习笔记之深入理解关键字static
来源:互联网 发布:printthis.js用法 编辑:程序博客网 时间:2024/06/05 20:29
基本概念
static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量这个概念。
在Java中,用static修饰的方法称为静态方法(类方法),用static修饰的变量称为静态变量(类变量)。
为什么需要static关键字?可以通过以下两种情形进行思考
- 情形一:只想为某特定域分配单一存储空间,而不去考虑究竟要创建多少对象,甚至根本就不创建任何对象。
- 情形二:希望某个方法不与包含它的类的任何对象关联在一起。也就是说,即使没有创建对象,也可以调用这个方法。
一般情况下,执行new来创建对象时,数据存储空间才被分配,其方法才供外界调用。要想解决以上两种情形,通过new肯定是不行的,而通过static关键字就可以满足这两方面的需要。
static有以下几个特点:
- 被static修饰的成员变量和成员方法独立于该类的任何对象。即不依赖于类特定的实例,被类的所有实例共享
- static变量和方法可以直接通过类来访问,而无需创建任何对象
- static方法是没有this的方法,即它不属于对象,而是属于类
- 在static方法内部不能访问非静态成员变量和非静态成员方法,因为非静态成员变量/方法是依赖于具体的对象,必须创建对象后才能使用(非绝对)
- 类的构造器实际上也是静态方法,只不过没有显示地声明
static变量
类成员变量可分为两类:静态变量和实例变量。静态变量不属于某个实例对象,而是属于类;而实例变量属于某个对象的属性。可通过以下代码进行理解
public class Test { static int a; int b; public static void main(String[] args) { Test test1 = new Test(); System.out.println(a); //System.out.println(b); //It's not OK! System.out.println(test1.b); //It's OK! Test test2 = new Test(); a = 1; test2.b = 1; System.out.println(a); System.out.println(test1.b); System.out.println(test2.b); }}
输出结果:
00101
具体区别可参考Java学习笔记之变量类型。
static方法
静态方法可以直接通过类名调用,任何的实例也都可以调用。但在static方法内部不能访问非静态成员变量和非静态成员方法,因为非静态成员变量/方法是依赖于具体的对象,必须创建对象后才能使用。这种说法不是完全绝对的,因为:如果传递一个对象的引用到静态方法里,然后通过这个引用就可以调用非静态方法和访问非静态数据成员了。但通常要达到这样的效果,我们只需写一个非静态方法即可,而无需传递引用。可通过以下代码进行理解:
public class staticDemo { public void print() { System.out.println("staticDemo!"); } // 静态方法 public static void printStatic() { //print(); // It's not OK! staticDemo demo = new staticDemo(); demo.print(); // 在静态方法中调用非静态方法必须先创建对象 } // 非静态方法 public void printNoStatic() { print(); }}
static代码块
static代码块也叫静态代码块,是在类中独立于类成员的static语句块,可以有多个,位置可以随便放,它不在任何的方法体内,JVM加载类时会执行这些静态的代码块,如果static代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次。
静态代码块可以用来优化程序性能,可通过以下程序进行理解:
class Person{ private Date birthDate; public Person(Date birthDate) { this.birthDate = birthDate; } boolean isBornBoomer() { Date startDate = Date.valueOf("1946"); Date endDate = Date.valueOf("1964"); return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0; }}
isBornBoomer是用来这个人是否是1946-1964年出生的,而每次isBornBoomer被调用的时候,都会生成startDate和birthDate两个对象,造成了空间浪费,如果改成这样效率会更好:
class Person{ private Date birthDate; private static Date startDate,endDate; static{ startDate = Date.valueOf("1946"); endDate = Date.valueOf("1964"); } public Person(Date birthDate) { this.birthDate = birthDate; } boolean isBornBoomer() { return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0; }}
静态代码块的执行顺序可根据以下代码进行理解:
class StaticCode { static { System.out.println("A"); } public void show() { System.out.println("Hello World !"); } }class StaticCodeDemo { static { System.out.println("B"); } public static void main(String[] args) { new StaticCode().show(); } static { System.out.println("C"); } }
输出结果:
BCAHello World !
static和final一起使用
- 对于static final修饰的变量,表示一旦赋值就不可修改,并且可通过类名直接访问
- 对于static final修饰的方法,表示该方法不可覆盖,并且可通过类名直接调用
对于static final修饰的引用类型对象,特别是容器类型(如ArrayList、HashMap),不可以改变容器对象本身(即不能改变将其引用指向其他对象),但可以修改容器中存放的对象。
可通过以下程序进行理解:
import java.util.ArrayList;public class StaticFinalDemo { private static final String STR_STATIC_FINAL = "a"; private static String strStatic = "b"; private final String strFinal = "c"; private static final ArrayList < String > ARRAY_LIST = new ArrayList < String > (); private void print() { System.out.println("-------------值处理前----------"); System.out.println("STR_STATIC_FINAL = " + STR_STATIC_FINAL); System.out.println("strStatic = " + strStatic); System.out.println("strFinal = " + strFinal); System.out.println("ARRAY_LIST = " + ARRAY_LIST); // STR_STATIC_FINAL = "aa"; // It's not OK! final表示终态,不可以改变变量本身 strStatic = "bb"; // 可进行更改 // strFinal = "cc"; // It's not OK! final表示终态,不可以改变变量本身 // ARRAY_LIST = new ArrayList<String>(); // It's not OK! final表示终态,不可以将ARRAY_LIST引用指向其他对象 ARRAY_LIST.add("d"); // 可以修改容器中存放的对象 System.out.println("-------------值处理后----------"); System.out.println("STR_STATIC_FINAL = " + STR_STATIC_FINAL); System.out.println("strStatic = " + strStatic); System.out.println("strFinal = " + strFinal); System.out.println("ARRAY_LIST = " + ARRAY_LIST); } public static void main(String args[]) { new StaticFinalDemo().print(); }}
输出结果:
-------------值处理前----------STR_STATIC_FINAL = astrStatic = bstrFinal = cARRAY_LIST = []-------------值处理后----------STR_STATIC_FINAL = astrStatic = bbstrFinal = cARRAY_LIST = [d]
参考资料
- Java编程思想
- Java中的static关键字解析
- Java学习笔记之深入理解关键字static
- Java学习笔记之深入理解关键字null
- Java学习笔记之深入理解关键字final
- Java学习笔记之深入理解关键字super
- Java学习笔记之关键字static
- Java学习笔记之static关键字。
- java学习笔记之static关键字
- 深入理解java的static关键字
- 深入理解java的static关键字
- 深入理解Java中static关键字
- Static关键字深入理解
- 学习笔记之关键字static
- Java学习笔记----static关键字
- Java学习笔记--static关键字
- Java学习之static关键字
- 学习Java之关键字 static
- Java学习之static关键字
- java学习笔记 static,final关键字学习
- php pdo用法例解
- BT是怎么下载的
- 面试技术总结
- kali linux下破解Wing IDE 5
- PDO多种方式取得查询结果
- Java学习笔记之深入理解关键字static
- EasyUI模糊查询
- ECLIPSE使用appcompat_v7库无法找到android:Widget.Material.ActionButton的问题
- 二叉树前序、中序、后序遍历相互求法
- springmvc异常处理-全局异常处理器开发
- el表达式_思维导图总结
- C++进阶教程之模板2--简单模板类(霜之小刀 附视频)
- pdo函数详解
- MFC的Ribbon界面状态栏加添进度条