zoukankan      html  css  js  c++  java
  • java-static修饰符

    什么是静态?

    概念:

      静态可以修饰属性和方法。

      称为静态属性(类属性)、静态方法(类方法)。

      静态成员是全类所有对象共享的成员。对象而产生

      在全类中只有一份(是全类对象共享的),不因创建多个对象而产生多份。

    静态属性代码:

    package day11;
    
    public class TestStatic {
    
    	public static void main(String[] args) {
    		ClassA a1=new ClassA();
    		ClassA a2=new ClassA();		
    		a1.m++;
    		a1.n++;
    		System.out.println(a2.m);//11
    		System.out.println(a2.n);//21
    	}
    }
    class ClassA{
    	int m=10;
    	static int n=20;
    	public static void print() {
    		//System.out.println(m);error
    		System.out.println(n);
    		//ma();这个会报红,因为在静态方法中调用了非静态方法
    		//mb();这个正确
    	}
    	public void ma() {}
    	public static void mb() {}
    	
    }

    static:

     属性:静态属性(静态属性不是在创建对象时有的)全类共有,可以直接拿类名访问。如ClassA.n

      静态变量跟对象没有关系,初始化是先于成员变量的。

     静态方法:静态能修饰属性,也能修饰方法。在静态方法中,不能访问非静态成员(方法和属性)。

      静态方法可以用类名引用。例子见如下图12行。

     在print()方法中,是不能直接调用ma()方法的,但是却可以通过对象的创建来引用:

    public static void print() {
    		//System.out.println(m);error
    		System.out.println(n);
    		//ma();这个会报红,因为在静态方法中调用了非静态方法 ma指的默认是this.ma() this:当前对象
    		ClassA a=new ClassA();
             a.ma();//运行结果:21
             问题:在静态方法中能有this吗? 不能 因为this指的是当前对象,而静态方法没有对象
    	}
    静态方法与静态方法之间的覆盖:
    package day11;
    
    public class TestStatic {
    
    	public static void main(String[] args) {
    		Super s=new Sub();
    		s.m();
    	}
    }
    
    class Super{
    	public static void m() {
    		System.out.println("Super");
    	}
    }
    class Sub extends Super{
    	public static void m() {
    		System.out.println("Sub");
    	}
    }
    

      运行结果:

       分析一下运行结果:按照之前的多态的思想(子类与父类有一样的方法,子类方法覆盖父类的方法),运行结果应该是Sub。思考:为什么会出现这样的结果呢?在静态方法中,是例外。静态方法的覆盖的情况下,编译器对引用类型去调用一个静态方法,结果输出引用类型的静态方法。结果为Super就不奇怪了。

      非静态方法不能覆盖父类的静态方法。因为会报错。静态方法自能被子类的静态方法覆盖,而且没有多态(只根据引用类型,调用相应的静态方法)。

      注:带有静态二字的都和对象没有什么关系。

    代码:

    package day11;
    
    public class TestDynamicBlock {
    
    	public static void main(String[] args) {
    		new MyClass();
    	}
    
    }
    class MyClass{
    	String field="实例属性";
    	{
    		System.out.println(field);
    		System.out.println("动态代码块");
    	}
    	public  MyClass(){
    		System.out.println("构造方法");
    	}
    }

      运行结果:

      初始代码块:静态初始代码块在类加载的时候执行。静态修饰静态初始代码块。

    类加载:

        当JVM第一次使用一个类时,读入这个类所对应的.class文件,并保存起来。  

      加载时机:

        创建对象。

        创建子类对象。(加载子类之前,先加载父类)

        访问静态属性。

        调用静态方法。

        Class.forName(“全限定名”)指名道姓的我要加载某个类

        将.class文件中对类的描述信息加载到内存中,进行保存。

          如:包名、类名、父类、属性、方法、构造方法...

        如果只是声明一个类的引用,不需要类加载。如A a;   A a=null;变量的本身不需要存对象,存的是对象的地址。

      类加载的步骤:

        1)如果需要,先加载父类。

        2)按顺序初始化静态属性,或执行静态初始代码块。按顺序执行。

    静态代码块例子1:

    package day11;
    
    public class TestDynamicBlock {
    
    	public static void main(String[] args) {
    //		new MyClass();
    //		new A();
    		System.out.println(A.m);
    //		new A();
    	}
    
    }
    class MyClass{
    	static String field="实例属性";
    	static {
    		System.out.println(field);
    		System.out.println("动态代码块");
    	}
    	public  MyClass(){
    		System.out.println("构造方法");
    	}
    }
    class A{
    	static int m=10;
    	static {
    		System.out.println("Load A");//类加载的时候执行
    	}
    	public A(){
    		System.out.println("A");
    	}
    }
    

      运行结果:

    例子2:

    package day11;
    
    public class TestDynamicBlock {
    
    	public static void main(String[] args) {
    //		new MyClass();
    //		new A();
    //		System.out.println(A.m);
    //		new A();
    		new B();
    	}
    
    }
    class MyClass{
    	static String field="实例属性";
    	static {
    		System.out.println(field);
    		System.out.println("动态代码块");
    	}
    	public  MyClass(){
    		System.out.println("构造方法");
    	}
    }
    class A{
    	static int m=10;
    	static {
    		System.out.println("Load A");//类加载的时候执行
    	}
    	public A(){
    		System.out.println("A");
    	}
    }
    class B extends A{
    	static {
    		System.out.println("Load B");
    	}
    	public B() {
    		System.out.println("B");
    	}
    }
    

      运行结果:

     为什么会出现这样的结果? new B();先加载B(加载B得先加载父类),再实现B对象(先调用父类方法)

  • 相关阅读:
    ajax基础
    Linux经常使用命令大全
    基于Proxy思想的Android插件框架
    linux date -d 的一些使用方法
    Mac电脑没有声音,苹果电脑没有声音怎么办
    通用PE u盘装Ghost Win7系统
    通用PE u盘启动盘制作
    Qt for iOS,Qt 与Objective C混合编程
    苹果开发工具:Xcode和Interface Builder
    IOS 使用Interface Builder开发界面入门与技巧
  • 原文地址:https://www.cnblogs.com/SpringChuXin/p/13790539.html
Copyright © 2011-2022 走看看