zoukankan      html  css  js  c++  java
  • 03-类与对象——课后动手动脑

    1.早期我们经常这样定义变量

                 int value=100;

         前面的示例中这样定义变量

                 MyClass obj = new MyClass();

    这两种方式定义的变量是一样的吗?

    这两种方式定义的变量是一样的,因为它们都是类的实例化,只是第一种是一个简便的写法,第二种是正常的对类进行实例化。

    2.对象变量也可以使用“==”判断两变量值是否相等吗?

    当“==”施加于引用类型变量时,是比较这两个变量是否引用同一对象,换句话说,“==”实际上相当于比较两个引用类型变量中保存的对象地址是否相同。

    在Java中要比对两个对象的字段值,可以重写基类的equals()方法。将其改成自己类的一个方法用来调用。

    3.请输入并运行以下代码,得到什么结果?

    public class Test {
    
        public static void main(String[] args) {
            Foo obj1=new Foo();
            Foo obj2=new Foo();
            System.out.println(obj1==obj2);
        }
    
    }
    class Foo{
        int value=100;
    }

    运行结果:

    原因:按照第2条,我们可知,“==”实际上相当于比较两个引用类型变量中保存的对象地址是否相同。obj1和obj2虽然都是Foo类型的变量,但其指向的空间或者地址不同,所以输出的是false。

    4.

    请总结一下,这个方法有哪些“与众不同之处”,你能列出几条?

     1.方法名与类名完全相同。

    2.无返回值,也没有void关键字。

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

    原因:在类中如果提供了一个构造函数,那么在进行类的实例化时,调用的就是这个构造函数。此例中,Foo类本身提供了一个有参构造函数,这就导致系统不会提供默认的构造函数,那么定义obj1时就无法调用无参构造函数,所以整个程序当中会出现错误。

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

    例:

     1 public class InitializeBlockClass {
     2 
     3     {
     4         
     5         field = 200;
     6         
     7     }
     8     
     9     public int field = 100;
    10     
    11     public InitializeBlockClass(int value){
    12         
    13         this.field = value;
    14         
    15     }
    16     
    17     public InitializeBlockClass(){
    18         
    19     }
    20     
    21     public static void main(String[] args) {
    22         // TODO Auto-generated method stub
    23         InitializeBlockClass obj = new InitializeBlockClass();
    24         
    25         System.out.println(obj.field);
    26         
    27         
    28         obj = new InitializeBlockClass(300);
    29         
    30         System.out.println(obj.field);
    31         
    32     }
    33 
    34 }

    运行结果:

    Java字段初始化的规律:

    如果有多个不同地方对字段进行初始化,那么该字段的最终取值取决于最后一次初始化。

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

    TestStaticInitializeBlock.java

     1 class Root
     2 {
     3     static{
     4         System.out.println("Root的静态初始化块");
     5     }
     6     {
     7         System.out.println("Root的普通初始化块");
     8     }
     9     public Root()
    10     {
    11         System.out.println("Root的无参数的构造器");
    12     }
    13 }
    14 class Mid extends Root
    15 {
    16     static{
    17         System.out.println("Mid的静态初始化块");
    18     }
    19     {
    20         System.out.println("Mid的普通初始化块");
    21     }
    22     public Mid()
    23     {
    24         System.out.println("Mid的无参数的构造器");
    25     }
    26     public Mid(String msg)
    27     {
    28         //通过this调用同一类中重载的构造器
    29         this();
    30         System.out.println("Mid的带参数构造器,其参数值:" + msg);
    31     }
    32 }
    33 class Leaf extends Mid
    34 {
    35     static{
    36         System.out.println("Leaf的静态初始化块");
    37     }
    38     {
    39         System.out.println("Leaf的普通初始化块");
    40     }    
    41     public Leaf()
    42     {
    43         //通过super调用父类中有一个字符串参数的构造器
    44         super("Java初始化顺序演示");
    45         System.out.println("执行Leaf的构造器");
    46     }
    47 
    48 }
    49 
    50 public class TestStaticInitializeBlock
    51 {
    52     public static void main(String[] args) 
    53     {
    54         new Leaf();
    55         
    56 
    57     }
    58 }

    执行结果:

    “静态初始化块的执行顺序”:

    1.静态初始化块只执行一次。

    2.创建子类型的对象时,也会导致父类型的静态初始化块的执行。

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

    在静态方法中使用new进行实例化,然后再调用非静态成员。

    例:

     1 public class Task {
     2     
     3     public int a = 2;
     4     
     5     static int b = 3;
     6     
     7     static void display()
     8     
     9     {
    10         
    11         Task t1 = new Task();
    12         
    13         System.out.println("a="+t1.a);
    14         
    15     }
    16     public static void main(String[] args) {
    17         // TODO Auto-generated method stub
    18         Task t2 = new Task();
    19         
    20         t2.display();
    21         
    22     }
    23 
    24 }

    执行结果:

    9.请看以下的神奇代码:

    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?

     首先,利用javap对该程序进行反汇编。结果如图:

    可以看到其调用了Integer中的valueOf方法,valueOf方法的源代码为:

    可以看到,valueOf(int i)调用了IntegerCache.cache,通过网上查找,我得到了它的源代码如下:

     1 private static class IntegerCache {
     2         static final int low = -128;
     3         static final int high;
     4         static final Integer cache[];
     5 
     6         static {
     7             // high value may be configured by property
     8             int h = 127;
     9             String integerCacheHighPropValue =
    10                 sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
    11             if (integerCacheHighPropValue != null) {
    12                 try {
    13                     int i = parseInt(integerCacheHighPropValue);
    14                     i = Math.max(i, 127);
    15                     // Maximum array size is Integer.MAX_VALUE
    16                     h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
    17                 } catch( NumberFormatException nfe) {
    18                     // If the property cannot be parsed into an int, ignore it.
    19                 }
    20             }
    21             high = h;
    22 
    23             cache = new Integer[(high - low) + 1];
    24             int j = low;
    25             for(int k = 0; k < cache.length; k++)
    26                 cache[k] = new Integer(j++);
    27 
    28             // range [-128, 127] must be interned (JLS7 5.1.7)
    29             assert IntegerCache.high >= 127;
    30         }
    31 
    32         private IntegerCache() {}
    33     }

    通过这两段代码,我们可知,在[-128,127]这个区间中“”==”比较的是这两个数的数值,但当超出这个范围时,其就会创建一个新的对象,对于对象来说,我们是无法通过“==”进行比较的,因为“==”比较的是这两个对象所指向的空间是否相同,所以第二个会输出false。

  • 相关阅读:
    C#练习记录(统计字符串中的字符数和计算最大值)
    C#练习记录(交换两个数)
    Cyberdebut's daily record_3
    SWJTU_LightMoon Training #16~20 补题
    zzh训练日志3
    SWJTU_LightMoon Training #11~15 补题
    Megumin's daily record3
    2017网络赛
    zzh的训练日志2
    Cyberdebut's daily record_2
  • 原文地址:https://www.cnblogs.com/guo-xu/p/7688886.html
Copyright © 2011-2022 走看看