1. 为何要使用静态变量、常量和方法java
一般,在处理问题,会遇到多个不一样的类要使用同一变量,常量或方法,然而,同一个常量在不一样的类中建立时系统都会为之分配内存,形成内存浪费,若是能将这些不一样类中的变量共享到一个内存中,那就大大减小了内存的使用,而静态变量(关键字 static)就是解决这个问题的。以下图所示:函数
2. 被声明的static的变量,常量和方法被称为静态成员,静态成员属于类全部,区别于个别对象,能够在本类或其余类使用类名“.”运算符调用静态成员。以下代码:ui
1 public class AnyThing { 2 static double PI = 3.1415; //在类中定义静态常量 3 static int id; //在类中定义静态变量 4 public static void method1(){ //在类中定义静态方法 5 6 } 7 public void method2(){ 8 System.out.println(AnyThing.PI); //调用静态常量 9 System.out.println(AnyThing.id); //调用静态变量 10 AnyThing.method1(); //调用静态方法 11 } 12 }
注意:(1) 虽然静态成员可使用“对象.静态成员”的形式进行调用,但一般不这么使用,这样容易混淆静态成员和非静态成员。this
(2) 在静态方法中不可使用this关键字。code
(3) 在静态方法中不能够直接调用非静态方法。orm
(4) 在Java中规定不能将方法中的局部变量声明为static的。对象
(5) 若是在执行类时,但愿先执行类的初始化动做,可使用static定义一个静态区域,例如blog
1 public class example{ 2 static{ 3 ... 4 } 5 }
当这段代码被执行时,首先执行static块中的程序,而且只会执行一次,即在类加载的时候就被执行,以后执行main()方法。而且只是自上而下的顺序执行。继承
3.在java中,静态方法和普通方法的区别:内存
一、在外部调用静态方法时,可使用"类名.方法名"的方式,也可使用"对象名.方法名"的方式。而实例方法只有后面这种方式。也就是说,调用静态方法能够无需建立对象。 二、静态方法在访问本类的成员时,只容许访问静态成员(即静态成员变量和静态方法),而不容许访问实例成员变量和实例方法;实例方法则无此限制。 三、程序的static块只能调用静态方法,不能调用实例的方法。 若是要追溯其区别的根源,能够这样理解:在编译期间静态方法的行为就已经肯定,而实例方法只有在运行期间当实例肯定以后才能肯定。
基本练习
package test_01; public class static_class { static int a =100; int b=200; //实例变量 public static void main(String[] args) { // TODO Auto-generated method stub // static int a =100; //局部变量不能定义static System.out.println("主函数"); static_fangfa(); //public_fangfa(); //也不能在静态函数中调用静态函数 ,除非把非静态函数变为静态函数 } // 静态块 static { System.out.println("静态块"); } public static_class() { // TODO Auto-generated constructor stub System.out.println("构造方法"); } private static void static_fangfa() { System.out.println("静态函数"); static_class static_class1 =new static_class(); System.out.println(static_class1.a); // System.out.println(static_class.b); // 静态函数里面不能调用静态变量 } public void public_fangfa() { int c = 100+b; System.out.println("非静态函数"+c); } }
输出结果:
静态块 主函数 静态函数 构造方法 100
4.静态代码段
a. 静态代码块只能定义在类里面,它独立于任何方法,不能定义在方法里面
b.静态代码块里面的变量都是局部变量,只在本块内有效
c.静态代码块会在类被加载时自动执行,而不管加载者是JVM仍是其余的类
d. 一个类中容许定义多个静态代码块,执行的顺序根据定义的顺序进行
e.静态代码块只能访问类的静态成员,而不容许访问实例成员
5.java中的初始化顺序
JAVA类首次装入时,会对静态成员变量或方法进行一次初始化,但方法不被调用是不会执行的,静态成员变量和静态初始化块级别相同,非静态成员变量和非静态初始化块级别相同。
初始化顺序:先初始化父类的静态代码--->初始化子类的静态代码-->
(建立实例时,若是不建立实例,则后面的不执行)初始化父类的非静态代码(变量定义等)--->初始化父类构造函数--->初始化子类非静态代码(变量定义等)--->初始化子类构造函数
类只有在使用New调用建立的时候才会被JAVA类装载器装入建立类实例时,首先按照父子继承关系进行初始化类实例建立时候,首先初始化块部分先执行,而后是构造方法;而后从本类继承的子类的初始化块执行,最后是子类的构造方法类消除时候,首先消除子类部分,再消除父类部分
static 函数名() --> 能够经过 类名.函数名() 调用,也能够经过 类对象.函数名() 调用;
函数名() -->只能经过类对象.函数名() 调用;
6.Java静态对象和非静态对象的区别
静态对象 非静态对象
拥有属性: 是类共同拥有的 是类各对象独立拥有的
内存分配: 内存空间上是固定的 空间在各个附属类里面分配
分配顺序: 先分配静态对象的空间 继而再对非静态对象分配空间,也就是初始化顺序是先静态再非静态。
7.Java静态对象的特色
A,静态对象的数据在全局是惟一的,一改都改。若是你想要处理的东西是整个程序中惟一的,弄成静态是个好方法。非静态的东西你修改之后只是修改了他本身的数据,可是不会影响其余同类对象的数据。
B,引用方便。直接用类名.静态方法名 或者 类名.静态变量名就可引用而且直接能够修改其属性值,不用get和set方法。
C,保持数据的惟一性。此数据全局都是惟一的,修改他的任何一处地方,在程序全部使用到的地方都将会体现到这些数据的修改。有效减小多余的浪费。
D,static final用来修饰成员变量和成员方法,可简单理解为“全局常量”。对于变量,表示一旦给值就不可修改;对于方法,表示不可覆盖。
8.静态变量、静态方法和静态块
一般状况下,类成员必须经过它的类的对象访问,可是能够建立这样一个成员,它可以被它本身使用,而没必要引用特定的实例。在成员的声明前面加上关键字static就能建立这样的成员。若是一个成员被声明为static,它就可以在它的类的任何对象建立以前被访问,而没必要引用任何对象(跟类是否有static修饰无关)。
你能够将方法和变量都声明为static。static 成员的最多见的 例子是main( ) 。声明为static的方法有如下几条限制: ·
A,它们仅能调用其余的static 方法
B,它们只能访问static数据
C,它们不能以任何方式引用this 或super(this涉及到对象,super 与继承有关)
示例:Static 块仅在该类被加载时执行一次。下面的例子显示的类有一个static方法,一些static变量,以及一个static 初始化块。
public class TestNew { static int a = 3; static int b; static void meth(int x){ System.out.println("x = "+x); System.out.println("a = "+a); System.out.println("b = "+b); } static { System.out.println("static block initialized"); b = a*4; } public static void main(String[] args) { // TODO Auto-generated method stub meth(42); } }
执行结果是:
static blockinitialized x = 42 a = 3 b = 12
上述classTestNew的执行顺序是:首先static 块执行(打印一条消息),a被设置为3,最后b被初始化为a*4 成12。而后调用main(),main () 调用meth() ,把值42传递给x。3个println ( ) 语句引用两个static变量a和b,以及局部变量x 。
9.外部使用静态变量或者静态方法
在定义它们的类的外面,static方法和变量能独立于任何对象而被使用,你只要在类的名字后面加点号运算符便可。能够看到,这种格式与经过对象引用变量调用非static方法或者变量的格式相似。示例:
class StaticDemo{ static int a = 42; static int b = 99; static void callme(){ System.out.println("a = "+a); } } public class TestNew { public static void main(String[] args) { // TODO Auto-generated method stub StaticDemo.callme(); System.out.println("b = "+StaticDemo.b); } }
执行结果:
a = 42 b = 99
10.静态内部类
静态内部类是指在一个类的内部,又定义了一个用static修饰的类。
A,首先,用内部类是由于内部类与所在外部类有必定的关系,每每只有该外部类调用此内部类。因此没有必要专门用一个Java文件存放这个类。
B,静态方法、静态成员变量。它惟一的做用就是随着类的加载(而不是随着对象的产生)而产生,以至能够用类名+静态成员名直接得到。这样静态内部类就能够理解了,它能够直接被用外部类名+内部类名得到。
public class Build { .............. public static class VERSION { ................ public static final String RELEASE =getString("ro.build.version.release"); ................ } ................ }
在外部能够直接经过Build.VERSION.RELEASE来访问。
11. 静态常量
静态常量不可变,能够直接被访问,如类名.静态常量名。例如:
public class MathTest{ public static final double PI= 3.1415926; }
能够直接采用MathTest.PI的形式访问该PI常量。
13. 静态类与内部类的区别
内部类
一、内部类拥有普通类的全部特性,也拥有类成员变量的特性
二、内部类能够访问其外部类的成员变量,属性,方法,其它内部类
静态内部类
一、只有内部类才能声明为static,也能够说是静态内部类
二、只有静态内部类才能拥有静态成员,普通内部类只能定义普通成员
三、静态类跟静态方法同样,只能访问其外部类的静态成员
四、若是在外部类的静态方法中访问内部类,这时候只能访问静态内部类
/** * 外部类,不能声明为 static * * @author zhanqi * */ public class OuterClass { private int ab = 1; private static int sab = 2; /** * 普通内部类 */ public class NormalInnerClass { // private static int age = 22; private int age = 22; // 不能声明为static public NormalInnerClass() { // 能够访问外部类静态与非静态成员 System.out.println(ab); System.out.println(sab); } } /** * 静态内部类 */ public static class StaticInnerClass { // 定义静态与非静态成员都是能够的 private static int age = 22; private int age2 = 22; private void echo() { // System.out.println(ab); System.out.println(sab);// 只能访问外部类的静态成员 } } }
内部类实例化
1.访问内部类,必须使用:外部类.内部类,OutClass.InnerClass
2.普通内部类必须绑定在其外部类的实例上
3.静态内部类能够直接 new
/** * 外部类访问内部类 */ public class OuterClass {/** * 普通方法 */ public void method() { StaticInnerClass sic = new StaticInnerClass(); NormalInnerClass nic = new NormalInnerClass(); }/** * Main */ public static void main(String[] args) { // 在静态方法中,只能访问静态成员,静态内部类 // NormalInnerClass nic = new NormalInnerClass(); StaticInnerClass sic = new StaticInnerClass(); } }/** * 其它类访问内部类 */ class Test { public static void main(String[] args) { /** * 1:其它类访问内部类,必须使用:外部类.内部类,OutClass.InnerClass * 2:普通内部类必须绑定在其外部类的实例上 * 3:静态内部类能够直接 new */ OuterClass.StaticInnerClass sic = new OuterClass.StaticInnerClass(); // OuterClass.NormalInnerClass n = new OuterClass.NormalInnerClass();OuterClass oc = new OuterClass(); OuterClass.NormalInnerClass nic = oc.new NormalInnerClass(); } }
静态对象
静态对象咱们常用,可是对静态对象和非静态对象的区别却并不必定那么了解。下表格就是静态对象和非静态对象主要区别。
1.拥有的对象,静态对象是类共同拥有的 ,而非静态对象是由类单独拥有; 2.内存空间,静态对象内存空间是固定,非静态类对象是附着相关类的分配; 3.分配顺序,先分配静态对象的空间,而后才会分配非静态对象也就是初始化。