zoukankan      html  css  js  c++  java
  • JAVA之类的动手动脑

    1.默认构造方法与自定义的构造方法的冲突

    package com.xu;
    class fool
    {
        int value;
        fool(int nowvalue)
        {
            value=nowvalue;
        }
    }
    public class hello {
        
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            fool f=new fool();
            
        }
    
    }

    可他为什么会报错呢?

    原因是:假如不去自定义构造函数方法,java编译器在编译时会自动提供一个没有参数的“默认构造方法”,上述代码即可成立

    然而,如果你自己定义了一个构造方法,将导致系统不再提供默认的构造方法,因此会报错,报错原因是你没有初始化的时候传入参数。

    2.java初始化的先后顺序

    package com.xu;
    public class hello {
        hello()
        {
            System.out.println("调用无参构造");
        }
        
        hello(int nowvalue)
        {
            this.value=nowvalue;
            System.out.println("调用有参构造");
        }
        
        {
            value=900;
            System.out.println("999");
        }
        
        public int value=200;
        
        
        
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            hello h1=new hello();
            System.out.println("无参构造的输出为:"+h1.value);
            
            hello h2=new hello(1000);
            System.out.println("有参构造的输出为:"+h2.value);
            
        }
    
    }

    输出为:

    999
    调用无参构造
    无参构造的输出为:200
    999
    调用有参构造
    有参构造的输出为:1000

    在初始化块和数据的指定值之间的执行数序是:谁在前就先执行谁

    对于构造函数在他们之后执行。

    3.静态初始化块的执行顺序

    class Root
    {
        static{
            System.out.println("Root的静态初始化块");
        }
        
        {
            System.out.println("Root的普通初始化块");
        }
        public Root()
        {
            System.out.println("Root的无参数的构造器");
        }
    }
    class Mid extends Root
    {
        static{
            System.out.println("Mid的静态初始化块");
        }
        {
            System.out.println("Mid的普通初始化块");
        }
        public Mid()
        {
            System.out.println("Mid的无参数的构造器");
        }
        public Mid(String msg)
        {
            //通过this调用同一类中重载的构造器
            this();
            System.out.println("Mid的带参数构造器,其参数值:" + msg);
        }
    }
    class Leaf extends Mid
    {
        static{
            System.out.println("Leaf的静态初始化块");
        }
        
        {
            System.out.println("Leaf的普通初始化块");
        }
        
        public Leaf()
        {
            //通过super调用父类中有一个字符串参数的构造器
            super("Java初始化顺序演示");
            System.out.println("执行Leaf的构造器");
        }
    
    }
    
    public class TestStaticInitializeBlock
    {
        public static void main(String[] args) 
        {
            new Leaf();
            
    
        }
    }

    输出为:

    Root的静态初始化块
    Mid的静态初始化块
    Leaf的静态初始化块
    Root的普通初始化块
    Root的无参数的构造器
    Mid的普通初始化块
    Mid的无参数的构造器
    Mid的带参数构造器,其参数值:Java初始化顺序演示
    Leaf的普通初始化块
    执行Leaf的构造器

    在构造子类对象时,会先构造父类对象,静态初始化块优先执行,其次是父类的非静态初始化块,父类的构造函数,然后是子类的非静态初始化块,子类的构造函数。

    4.在静态方法中访问非静态成员和方法

    我们都知道在静态方法中不能直接访问非静态的成员及方法

    那么,我们就真的不能吗?

    当然也可以,我们可以在静态方法中实例化包含非静态方法的类的对象。这样通过对象就可以间接的访问非静态方法和数据

    package com.xu;
    public class hello {
        public int value=0;
        
        
        public int getValue() {
            return value;
        }
    
    
        public void setValue(int value) {
            this.value = value;
        }
    //静态方法中调用非静态的成员及方法
        static void f()
        {
            hello s=new hello();
            System.out.println(s.getValue());
            int k=10;
            s.setValue(k);
            System.out.println(s.getValue());
        }
        
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            f();
        }
    
    }

    输出:

    0

    10

    5.诡异的Integer

    public class StrangeIntegerBehavior 
    {
    
        
        public static void main(String[] args)
        {
    
            
            Integer i1=100;
           
            Integer j1=100;
            
            System.out.println(i1==j1);
    
            
            Integer i2=129;
            
            Integer j2=129;
            
            System.out.println(i2==j2);
        
        }
    
    
    }

    输出:

    true
    false

    为什么第二个会是false呢?

    java在编译Integer x = yyy ;时,会翻译成为Integer x = Integer.valueOf(yyy)。而java API中对Integer类型的valueOf的定义如下,对于-128到127之间的数,会进行缓存,Integer i = 127时,会将127进行缓存,下次再写Integer j = 127时,就会直接从缓存中取,就不会new了。如果超过128就会重新new一个新对象。

    所以i2和j2都是重新new的对象,故他们的地址不同,输出为false。

    而i1和j1都是缓存过的,用的时候直接提取出来即可,因而他们的地址是一样的。

    课后作业

    1.使用类的静态字段和构造函数,可以跟踪某个类所创建对象的个数。请写一个类,在任何时候都可向他查询生成多少个对象

    package com.xu;
    public class hello {
        static int num=0;
        hello()
        {
            num++;
            System.out.println("已创建"+num+"个对象");
        }
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            hello h1=new hello();
            hello h2=new hello();
            hello h3=new hello();
            System.out.println("一共创建了"+num+"个对象");
        }
    
    }

    输出:

    已创建1个对象
    已创建2个对象
    已创建3个对象
    一共创建了3个对象

  • 相关阅读:
    Delphi公用函数单元
    Delphi XE5 for Android (十一)
    Delphi XE5 for Android (十)
    Delphi XE5 for Android (九)
    Delphi XE5 for Android (八)
    Delphi XE5 for Android (七)
    Delphi XE5 for Android (五)
    Delphi XE5 for Android (四)
    Delphi XE5 for Android (三)
    Delphi XE5 for Android (二)
  • 原文地址:https://www.cnblogs.com/xiaofengzai/p/11684855.html
Copyright © 2011-2022 走看看