动手动脑_10.17

一、以下代码为何无法通过编译?哪儿出错了?

    

    答:如果没有构造方法,类会提供一个默认的。类提供了一个自定义的构造方法,导致系统不再提供默认构造方法。

二、如果一个类中既有初始化块,又有构造方法,同时还设定了字段的初始值,谁说了算?

    答:1、执行类成员定义时指定的默认值或类的初始化块,到底执行哪一个要看哪一个“排在前面”。

      2、执行类的构造函数。

    类的初始化块不接收任何的参数,而且只要一创建类的对象,它们就会被执行。因此,适合于封装那些“对象创建时必须执行的代码”。

三、请运行TestStaticInitializeBlock.java示例,观察输出结果,总结出“静态初始化块的执行顺序”。

    答:1、静态初始化块的优先级最高,也就是最先执行,并且仅在类第一次被加载时执行;

      2、非静态初始化块和构造函数后执行,并且在每次生成对象时执行一次;

      3、非静态初始化块的代码会在类构造函数之前执行。因此若要使用,应当养成把初始化块写在构造函数之前的习惯,便于调试;

      4、静态初始化块既可以用于初始化静态成员变量,也可以执行初始化代码;

      5、非静态初始化块可以针对多个重载构造函数进行代码复用。

四、静态方法中只允许访问静态数据,那么,如何在静态方法中访问类的实例成员(即没有附加static关键字的字段或方法)?

  答: public class Test{
   int j =5;
   static int value; 
   public static void A()
   {

      System.out.println(value); 

  } 
   public int B()
   {  
      int x = 100;  
      return x; 
    }  
   public static void main(String args[]) {  
      Test3 a = new Test3(); 
      value = a.B(); 
      a.A(); 
    }

  } 

五、两对整数明明完全一样,为何一个输出true,一个输出false?

              

      答:

原因很简单:

输出结果表明i1和i2指向的是同一个对象,而i3和i4指向的是不同的对象。此时只需一看源码便知究竟,下面这段代码是Integer的valueOf方法的具体实现:

public static Integer valueOf(int i) {
        if(i >= -128 && i <= IntegerCache.high)
            return IntegerCache.cache[i + 128];
        else
            return new Integer(i);
    }
public static Integer valueOf(int i) {
        if(i >= -128 && i <= IntegerCache.high)
            return IntegerCache.cache[i + 128];
        else
            return new Integer(i);
    }

  而其中IntegerCache类的实现为:

 private static class IntegerCache {
        static final int high;
        static final Integer cache[];

        static {
            final int low = -128;

            // high value may be configured by property
            int h = 127;
            if (integerCacheHighPropValue != null) {
                // Use Long.decode here to avoid invoking methods that
                // require Integer‘s autoboxing cache to be initialized
                int i = Long.decode(integerCacheHighPropValue).intValue();
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - -low);
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
        }

        private IntegerCache() {}
    }
技术分享
 private static class IntegerCache {
        static final int high;
        static final Integer cache[];

        static {
            final int low = -128;

            // high value may be configured by property
            int h = 127;
            if (integerCacheHighPropValue != null) {
                // Use Long.decode here to avoid invoking methods that
                // require Integer‘s autoboxing cache to be initialized
                int i = Long.decode(integerCacheHighPropValue).intValue();
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - -low);
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
        }

        private IntegerCache() {}
    }
技术分享

  从这2段代码可以看出,在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象。

  上面的代码中i1和i2的数值为100,因此会直接从cache中取已经存在的对象,所以i1和i2指向的是同一个对象,而i3和i4则是分别指向不同的对象。(查资料)

 

posted @ 2017-10-19 22:12  浪花98  阅读(144)  评论(0编辑  收藏  举报