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个对象

  • 相关阅读:
    移动布局---1. 移动端布局基础
    1. CSS新特性之选择器
    1. H5新增语义化标签
    POJ 3281
    poj 1986
    POJ 3728
    poj 2763
    poj 2749
    uva 11294
    LA 3713
  • 原文地址:https://www.cnblogs.com/xiaofengzai/p/11684855.html
Copyright © 2011-2022 走看看