Java中static作用及使用方法具体解释
1.1概述:
static是静态修饰符,什么叫静态修饰符呢?大家都知道,在程序中不论什么变量或者代码都是在编译时由系统自己主动分配内存来存储的。而所谓静态就是指在编译后所分配的内存会一直存在。直到程序退出内存才会释放这个空间,也就是仅仅要程序在执行,那么这块内存就会一直存在。这样做有什么意义呢?在Java程序里面,全部的东西都是对象,而对象的抽象就是类,对于一个类而言,假设要使用他的成员,那么一般情况下必须先实例化对象后。通过对象的引用才可以訪问这些成员,可是用static修饰的成员可以通过类名加“.”进行直接訪问。
static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也能够形成静态static代码块,可是Java语言中没有全局变量的概念。
被static修饰的成员变量和成员方法独立于该类的不论什么对象。也就是说,它不依赖类特定的实例,被类的全部实例共享。
仅仅要这个类被载入。Java虚拟机就能依据类名在执行时数据区的方法区内定找到他们。
因此,static对象能够在它的不论什么对象创建之前訪问,无需引用不论什么对象。
用public修饰的static成员变量和成员方法本质是全局变量和全局方法。当声明它类的对象市,不生成static变量的副本,而是类的全部实例共享同一个static变量。
static变量前能够有private修饰,表示这个变量能够在类的静态代码块中,或者类的其它静态成员方法中使用(当然也能够在非静态成员方法中使用--废话),可是不能在其它类中通过类名来直接引用。这一点非常重要。实际上你须要搞明确,private是訪问权限限定。static表示不要实例化就能够使用,这样就easy理解多了。
static前面加上其它訪问权限keyword的效果也以此类推。
static修饰的成员变量和成员方法习惯上称为静态变量和静态方法,能够直接通过类名来訪问,訪问语法为:
类名.静态方法名(參数列表...)
类名.静态变量名
用static修饰的代码块表示静态代码块,当Java虚拟机(JVM)载入类时。就会运行该代码块(用处很大。呵呵)。
1.2 static变量
依照是否静态的对类成员变量进行分类可分两种:一种是被static修饰的变量,叫静态变量或类变量;还有一种是没有被static修饰的变量,叫实例变量。两者的差别是:
对于静态变量在内存中仅仅有一个拷贝(节省内存),JVM仅仅为静态分配一次内存,在载入类的过程中完毕静态变量的内存分配,可用类名直接訪问(方便)。当然也能够通过对象来訪问(可是这是不推荐的)。
对于实例变量。没创建一个实例。就会为实例变量分配一次内存,实例变量能够在内存中有多个拷贝,互不影响(灵活)。
1.3static方法
静态方法能够直接通过类名调用,不论什么的实例也都能够调用。因此静态方法中不能用this和superkeyword,不能直接訪问所属类的实例变量和实例方法(就是不带static的成员变量和成员成员方法),仅仅能訪问所属类的静态成员变量和成员方法。由于实例成员与特定的对象关联!这个须要去理解,想明确当中的道理,不是记忆!。!由于static方法独立于不论什么实例,因此static方法必须被实现,而不能是抽象的abstract。
1.4static代码块
static代码块也叫静态代码块,是在类中独立于类成员的static语句块。能够有多个,位置能够随便放,它不在不论什么的方法体内,JVM载入类时会运行这些静态的代码块。假设static代码块有多个,JVM将依照它们在类中出现的先后顺序依次运行它们,每一个代码块仅仅会被运行一次。比如:
public class Test5 { private static int a; private int b; static { Test5.a = 3; System.out.println(a); Test5 t = new Test5(); t.f(); t.b = 1000; System.out.println(t.b); } static { Test5.a = 4; System.out.println(a); } public static void main(String[] args) { // TODO 自己主动生成方法存根 } static { Test5.a = 5; System.out.println(a); } public void f() { System.out.println("hhahhahah"); } }
执行结果:
3
hhahhahah
1000
4
5
利用静态代码块能够对一些static变量进行赋值。最后再看一眼这些样例,都一个static的main方法,这样JVM在执行main方法的时候能够直接调用而不用创建实例。
1、 static和final一块用表示什么
static final用来修饰成员变量和成员方法,可简单理解为“全局常量”。
对于变量。表示一旦给值就不可改动。而且通过类名能够訪问。
对于方法,表示不可覆盖,而且能够通过类名直接訪问。
特别要注意一个问题:
对于被static和final修饰过的实例常量。实例本身不能再改变了,但对于一些容器类型(比方,ArrayList、HashMap)的实例变量,不能够改变容器变量本身,但能够改动容器中存放的对象,这一点在编程中用到非常多。看个样例:
public class TestStaticFinal { private static final String strStaticFinalVar ="aaa"; private static String strStaticVar =null; private final String strFinalVar = null; private static final int intStaticFinalVar = 0; private static final Integer integerStaticFinalVar =new Integer(8); private static final ArrayList<String>alStaticFinalVar = new ArrayList<String>(); private void test() { System.out.println("-------------值处理前----------\r\n"); System.out.println("strStaticFinalVar=" +strStaticFinalVar + "\r\n"); System.out.println("strStaticVar=" +strStaticVar + "\r\n"); System.out.println("strFinalVar=" +strFinalVar + "\r\n"); System.out.println("intStaticFinalVar=" +intStaticFinalVar + "\r\n"); System.out.println("integerStaticFinalVar=" +integerStaticFinalVar + "\r\n"); System.out.println("alStaticFinalVar=" +alStaticFinalVar + "\r\n"); //strStaticFinalVar="哈哈哈哈"; //错误,final表示终态,不能够改变变量本身. strStaticVar = "哈哈哈哈"; //正确,static表示类变量,值能够改变. //strFinalVar="呵呵呵呵"; //错误, final表示终态,在定义的时候就要初值(哪怕给个null),一旦给定后就不可再更改。 //intStaticFinalVar=2; //错误, final表示终态,在定义的时候就要初值(哪怕给个null)。一旦给定后就不可再更改。//integerStaticFinalVar=new Integer(8); //错误, final表示终态,在定义的时候就要初值(哪怕给个null)。一旦给定后就不可再更改。
alStaticFinalVar.add("aaa"); //正确,容器变量本身没有变化,但存放内容发生了变化。
这个规则是非经常常使用的,有非常多用途。 alStaticFinalVar.add("bbb"); //正确,容器变量本身没有变化,但存放内容发生了变化。这个规则是非经常常使用的,有非常多用途。 System.out.println("-------------值处理后----------\r\n"); System.out.println("strStaticFinalVar=" +strStaticFinalVar + "\r\n"); System.out.println("strStaticVar=" +strStaticVar + "\r\n"); System.out.println("strFinalVar=" +strFinalVar + "\r\n"); System.out.println("intStaticFinalVar=" +intStaticFinalVar + "\r\n"); System.out.println("integerStaticFinalVar=" +integerStaticFinalVar + "\r\n"); System.out.println("alStaticFinalVar=" +alStaticFinalVar + "\r\n"); } public static void main(String args[]) { new TestStaticFinal().test(); } }
执行结果例如以下:
-------------值处理前----------
strStaticFinalVar=aaa
strStaticVar=null
strFinalVar=null
intStaticFinalVar=0
integerStaticFinalVar=8
alStaticFinalVar=[]
-------------值处理后----------
strStaticFinalVar=aaa
strStaticVar=哈哈哈哈
strFinalVar=null
intStaticFinalVar=0
integerStaticFinalVar=8
alStaticFinalVar=[aaa, bbb]Process finished with exit code 0
看了上面这个样例,就清楚非常多了,但必须明确:通过static final修饰的容器类型变量中所“装”的对象是可改变的。这是和一般基本类型和类类型变量区别非常大的地方。
1.5 java static块和static方法的使用差别
假设有些代码必须在项目启动的时候就运行,就须要使用静态代码块,这样的代码是主动运行的;须要在项目启动的时候就初始化可是不运行,在不创建对象的情况下,能够供其它程序调用,而在调用的时候才运行,这须要使用静态方法,这样的代码是被动运行的。
静态方法在类载入的时候 就已经载入 能够用类名直接调用。
静态代码块和静态方法的差别是:
• 静态代码块是自己主动运行的;
• 静态方法是被调用的时候才运行的.
• 静态方法:假设我们在程序编写的时候须要一个不实例化对象就能够调用的方法,我们就能够使用静态方法,详细实现是在方法前面加上static,例如以下:
public static void method(){}
在使用静态方法的时候须要注意一下几个方面:
在静态方法里仅仅能直接调用同类中其它的静态成员(包含变量和方法),而不能直接訪问类中的非静态成员。
这是由于。对于非静态的方法和变量,须要先创建类的实例对象后才可使用。而静态方法在使用前不用创建不论什么对象。(备注:静态变量是属于整个类的变量而不是属于某个对象的)
静态方法不能以不论什么方式引用this和superkeyword。由于静态方法在使用前不用创建不论什么实例对象,当静态方法调用时,this所引用的对象根本没有产生。
静态程序块:当一个类须要在被加载时就运行一段程序,这样能够使用静态程序块。
1.6总结
有时你希望定义一个类成员,使它的使用全然独立于该类的不论什么对象。
通常情况下,类成员必须通过它的类的对象訪问,可是可以创建这样一个成员,它可以被它自己使用,而不必引用特定的实例。在成员的声明前面加上keywordstatic(静态的)就能创建这种成员。假设一个成员被声明为static,它就行在它的类的不论什么对象创建之前被訪问,而不必引用不论什么对象。
你可以将方法和变量都声明为static。static 成员的最常见的样例是main( ) 。
由于在程序開始运行时必须调用main() ,所以它被声明为static。
声明为static的变量实质上就是全局变量。当声明一个对象时,并不产生static变量的拷贝。而是该类全部的实例变量共用同一个static变量。声明为static的方法有下面几条限制:
• 它们仅能调用其它的static方法。
• 它们仅仅能訪问static数据。
• 它们不能以不论什么方式引用this或super(keywordsuper 与继承有关。在下一章中描写叙述)。
假设你须要通过计算来初始化你的static变量,你能够声明一个static块。Static 块仅在该类被载入时运行一次。