zoukankan      html  css  js  c++  java
  • java基础-对象-练习集锦

    对象属性初始化有3种

    1. 声明该属性的时候初始化
    2. 构造方法中初始化
    3. 初始化块

    类属性初始化有2种

    1. 声明该属性的时候初始化
    2. 静态初始化块

    ===========================

    练习-属性初始化

    对象属性的初始化有三种方式
    故意把初始化块,放在构造方法下面,问题:

    这三种方式,谁先执行?谁后执行?

    package charactor;
      
    public class Hero {
        public String name =Hero.getName("属性声明") ;
          
        public Hero(){
            name = Hero.getName("构造方法");
        }
        {
            name = Hero.getName("初始化块");
        }
         
        public static String getName(String pos){
            String result= "name "+pos;
            System.out.println(result);
            return result;
        }
         
        public static void main(String[] args) {
            new Hero();
        }
         
    }
    

    =============================
    解读静态代码块,构造代块和构造函数的先后顺序。
    顺序:
    初始化属性-->代码块-->构造函数

    静态变量初始化 的 值 只跟随 最后一次 初始化

    总结

    静态类属性顺序: 1:静态声明 2:静态代码块
    普通对象属性顺序:1: 属性声明 2:代码块 3:构造方法

    public class Hero {
    	public static int a=9;
    	static{
    		a=10;
    	}
    	public static void main(String[] args) {
    		System.out.println(Hero.a);  //10
    	}
    
    	
    }
    
    public class Hero {
    	public String name ="1";
    	public Hero(){
    		name ="2";
    	}
    	{
    		name="3";
    	}
    
    	public static void main(String[] args) {
    		Hero hero = new Hero();
    		System.out.println(hero.name);//输出2
    	}
    }
    

    ===============================
    static 面试题

    1.

    至于为什么是这个结果,我们先不讨论,先来想一下这段代码具体的执行过程,在执行开始,先要寻找到main方法,因为main方法是程序的入口,但是在执行main方法之前,必须先加载Test类,而在加载Test类的时候发现Test类继承自Base类,因此会转去先加载Base类,在加载Base类的时候,发现有static块,便执行了static块。在Base类加载完成之后,便继续加载Test类,然后发现Test类中也有static块,便执行static块。在加载完所需的类之后,便开始执行main方法。在main方法中执行new Test()的时候会先调用父类的构造器,然后再调用自身的构造器。因此,便出现了上面的输出结果。

    笔记:static代码块 是先于static main()方法执行的, 它是在类加载时 就开始的。 比运行main()还要先
    凡是涉及到类加载的时候,就要首先执行static代码块里的东西,如果有继承的话,再继续加载父类,执行父类里的代码块
    类的成员属性初始化,再到普通代码块初始化,然后再到构造方法初始化
    如果是静态的话, 静态成员属性初始化先,再到静态代码块初始化

    这段代码的输出结果是什么?

    public class Test {
        Person person = new Person("Test");
        static{
            System.out.println("test static");
        }
         
        public Test() {
            System.out.println("test constructor");
        }
         
        public static void main(String[] args) {
            new MyClass();
        }
    }
     
    class Person{
        static{
            System.out.println("person static");
        }
        public Person(String str) {
            System.out.println("person "+str);
        }
    }
     
     
    class MyClass extends Test {
        Person person = new Person("MyClass");
        static{
            System.out.println("myclass static");
        }
         
        public MyClass() {
            System.out.println("myclass constructor");
        }
    }
    

    类似地,我们还是来想一下这段代码的具体执行过程。首先加载Test类,因此会执行Test类中的static块。接着执行new MyClass(),而MyClass类还没有被加载,因此需要加载MyClass类。在加载MyClass类的时候,发现MyClass类继承自Test类,但是由于Test类已经被加载了,所以只需要加载MyClass类,那么就会执行MyClass类的中的static块。在加载完之后,就通过构造器来生成对象。而在生成对象的时候,必须先初始化父类的成员变量,因此会执行Test中的Person person = new Person(),而Person类还没有被加载过,因此会先加载Person类并执行Person类中的static块,接着执行父类的构造器,完成了父类的初始化,然后就来初始化自身了,因此会接着执行MyClass中的Person person = new Person(),最后执行MyClass的构造器。

    3.这段代码的输出结果是什么?

    public class Test {
         
        static{
            System.out.println("test static 1");
        }
        public static void main(String[] args) {
             
        }
         
        static{
            System.out.println("test static 2");
        }
    }
    

    自己给自己个考题

    package zsc.czy.object;
    
    public class Hero {
    	public String name = "hahah";
    	public Hero(){
    		name ="2";
    	}
    	static{
    		System.out.println("静态代码块");
    	}
    	{
    		System.out.println(name);
    	}
    
    	public static void main(String[] args) {
    		Hero hero = new Hero();
    
    	}
    }
    
    

    输出:
    静态代码块
    hahah

    package zsc.czy.object;
    
    public class Hero {
    	public String name = "hahah";
    	public Hero(){
    		name ="2";
    	}
    	static{
    		System.out.println("静态代码块");
    	}
    	{
    		System.out.println(name);
    	}
    
    	public static void main(String[] args) {
    
    	}
    }
    

    以上证明了:
    1:在执行开始,先要寻找到main方法,因为main方法是程序的入口,但是在执行main方法之前,必须先加载Hero类,而在加载Hero类时,发现有static块,便执行了static块
    2:每new XX() ; 就会加载这个XX类。如果加载XX类的时候发现XX类继承自AA类,因此会转去先加载AA类 ,这里发现有static块,便执行了static块
    3:类在加载完之后,就通过构造器来生成对象。而在生成对象的时候,必须先初始化父类的成员变量

    自己弄的问题

    package zsc.czy.object;
    
    public class Hero {
    	public static Hero hero = new Hero();
    	static {
    		System.out.println("静态代码块");
    	}
    	public Hero(){
    		System.out.println("被初始化了");
    	}
    	
    	
    	public static void main(String[] args) {
    	}
    }
    
    

    说明了:执行main()方法前,先Hero类加载, 按顺序,先静态成员初始化,再执行静态代码块 ;

    package zsc.czy.object;
    
    public class Hero {
    	public static Hero hero = new Hero();
    	static {
    		System.out.println("静态代码块");
    	}
    	{
    		System.out.println("普通代码块");
    	}
    	public Hero(){
    		System.out.println("被初始化了");
    	}
    	
    	
    	public static void main(String[] args) {
    	}
    }
    
    

    证实了:执行main()方法前,先Hero类加载, 按顺序,先静态成员初始化,执行有new 对象的语句,(顺序,先普通成员初始化,再普通代码块初始化,再到构造函数) 。完后再接着到执行静态代码块 ;

    自己想出的题目

    package zsc.czy.object;
    
    public class Hero {
    	
    	public static Hero hero = new Hero();
    	
    	static {
    		System.out.println("静态代码块");
    	}
    	
    	public String name ="1";
    	
    	{
    		name="2";
    	}
    	
    	
    	public Hero(){
    		System.out.println(name);
    	}
    	
    	
    	public static void main(String[] args) {
    		
    	}
    }
    
    

    自己出的题

    package zsc.czy.object;
    
    public class B {
    			public static String name="33";   
    		
    			static {   
    				name = "2";
    			}
    			
    		 
    			{
    				System.out.println("普通代码块");
    			}
    			
    			public B(){
    				System.out.println("构造方法");
    			}
    			
    			public static void main(String[] args) {
    				System.out.println(B.name);
    			}
    
    	}
    
    
    
    

    终极总结:

    顺序, 静态成员初始化 -->静态代码块初始化 -->普通对象成员初始哈 -->普通代码块初始化-->构造方法初始化

  • 相关阅读:
    源码分析:Java对象的内存分配
    源码分析:Java堆的创建
    Java Main如何被执行?
    HotSpot模板解释器目标代码生成过程源码分析
    Java常量池解析与字符串intern简介
    Java类的连接与初始化 (及2013阿里初始化笔试题解析)
    css中对position的几种定位方式的最佳诠释
    DB2学习笔记
    three.js:Failed to execute 'texImage2D' on 'WebGLRenderingContext解决方案
    线程隔离ThreadLocal
  • 原文地址:https://www.cnblogs.com/czy16/p/8943793.html
Copyright © 2011-2022 走看看