zoukankan      html  css  js  c++  java
  • “==”符的注意事项、类的构造与使用、静态初始块的执行顺序

    一、==符的使用

    问题:

    观察以下代码,两对整数明明完全一样,为何一个输出true,一个输出false

     

    原因分析:

    (1)知识点:

    当“==”施加于原始数据类型变量时,是比较变量所保存的数据是否相等。

    当“==”施加于引用类型变量时,是比较这两个变量是否引用同一对象。

    (2)通过查看Integer.java这个类就清楚了。当声明一个Integer j1 = 100;的时候。此时会进行自动装箱操作,也就是把基本数据类型转换成Integer对象,Integer中把-128~127 缓存了下来。官方解释是小的数字使用的频率比较高,所以为了优化性能,把这之间的数缓存了下来。这就是为什么这道题的答案回事false和ture了。当声明的Integer对象的值在-128~127之间的时候,引用的是同一个对象,所以结果是true。

     

    二、关于类的构造和引用:

    问题:

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

     

    原因分析:

    如果类提供了一个自定义的构造方法,将导致系统不再提供默认构造方法。因此必须使用自定义的构造方法中的参数类型。

    修改方法:

    如下图被荧光笔标注的部分,括号里的参数应该存放int类型的参数。

     

     

    三、构造函数

    问题1

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

     

    问题2

    使用问题1中的幻灯片中定义的类,以下代码输出结果是什么?

     

     

    提示:

    这是一个生造出来展示Java语法特性的示例类,在实际开发中不要这样写代码,应该尽量保证一个字段只初始化一次!

    (1)运行结果与分析:

     

    第一次创建nitializeBlockClass()类时,括号里面没有参数,因此输出中的obj.field等于nitializeBlockClass类中自定义的数据:100.

    第二次创建nitializeBlockClass(300)时,括号里面有和自定义的public InitializeBlockClass(int value)的构造函数,且函数中做了this.field=value;的操作,因此结果为300。

    从以上可以看出Java字段初始化规律:

    Java进行初始化的地方有两个:初始化块和构造函数,其中初始化块又分为静态初始化块和实例初始化块。静态初始化块是类中由static修饰的初始化块,实例初始化块为类中没有任何关键字修饰的初始化语句。

    当定义类时,先找寻是否有自定义构造函数,若有则引用,没有则使用默认构造函数。

    (2)类的总的加载及初始化顺序为:

    静态变量--静态初始化块--静态方法--非静态变量--非静态初始化块--非静态方法--构造器。

    四、静态初始化块的执行顺序:

    问题:

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

    TestStaticInitializeBlock.java源代码如下:

    class Root

    {

             static{

                       System.out.println("Root的静态初始化块");//【1】

             }

             {

                       System.out.println("Root的普通初始化块");//【4】

             }

             public Root()

             {

                       System.out.println("Root的无参数的构造器");//【5】

             }

    }

    class Mid extends Root

    {

             static{

                       System.out.println("Mid的静态初始化块");//【2】

             }

             {

                       System.out.println("Mid的普通初始化块");//【6】

             }

             public Mid()

             {

                       System.out.println("Mid的无参数的构造器");//【7】

             }

             public Mid(String msg)

             {

                       //通过this调用同一类中重载的构造器

                       this();

                       System.out.println("Mid的带参数构造器,其参数值:" + msg); //【8】

             }

    }

    class Leaf extends Mid

    {

             static{

                       System.out.println("Leaf的静态初始化块");//【3】

             }

             {

                       System.out.println("Leaf的普通初始化块");//【10】

             }      

             public Leaf()

             {

                       //通过super调用父类中有一个字符串参数的构造器

                       super("Java初始化顺序演示");//【9】

                       System.out.println("执行Leaf的构造器");//【11】

             }

     

    }

     

    public class TestStaticInitializeBlock

    {

             public static void main(String[] args)

             {

                       new Leaf();

                      

     

             }

    }

     输出结果顺序在源代码后用“//【顺序号】”标注。

    运行结果:

     

    原因分析:

    ①其中使用了super 和extends方法,具体使用方法如下。

    ②类的总的加载及初始化顺序为:静态变量--静态初始化块--静态方法--非静态变量--非静态初始化块--非静态方法--构造器。

    (一)、super的用法:

    super指父类,子类自动继承父类的属性和方法(除private修饰),一般情况下,直接使用父类的属性和方法,也可使用 this来指明本对象,但有时为了明确指明父类的属性和方法,使用关键字super。但使用super不能访问子类自己定义的属性和方法。

    super出现在继承了父类的子类中,有三种存在方式如下:

    ①super.xxx;(xxx为变量名或对象名)

    这种方法意义为:获取父类中的名字为xxx的变量或方法引用。

    使用这种方法可以直接访问父类中的变量或对象,进行修改赋值等操作

    ②super.xxx();(xxx为方法名)

    这种方法意义为:直接访问并调用父类中的方法。

    ③super();

    这种方法意义为:调用父类的初始化方法,其实就是调用父类中的public xxx()方法

    原文链接 :http://blog.csdn.net/crazy_kid_hnf/article/details/53188677##1

    (二)super使用注意事项:

    在使用super时,super指的是调用“对象”本身,而不是父类中看见的属性和方法。由于他指的是对象,所以不能在static的环境中使用,包括类变量(static field)、类方法(static method)和static语句块。

    (三)Java中“extends”与 “implements”的区别:

    1.在类的声明中,通过关键字extends来创建一个类的子类。一个类通过关键字implements声明自己使用一个或者多个接口。

    extends是继承某个类,继承之后可以使用父类的方法,也可以重写父类的方法;implements 是实现多个接口,接口的方法一般为空的,必须重写才能使用。

    2.extends是继承父类,只要那个类不是声明为final或者那个类定义为abstract的就能继承,JAVA中不支持多重继承,但是可以用接口来实现,这样就要用到implements,继承只能继承一个类,但implements可以实现多个接口,用逗号分开就行了

    比如

    Class  A  extends  B  mplements  C,D,E

    extends是继承父类,只要那个类不是声明为final或者那个类定义为abstract的就能继承,JAVA中不支持多重 继承,但是可以用接口来实现,这样就要用到implements,继承只能继承一个类,但implements可以实现多个接口,用逗号分开就行了

    比如

    Class  A  extends  B  implements  C,D,E

    参考文献:https://wenku.baidu.com/view/70c59d155f0e7cd1842536d2.html

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

    解决方法:

          在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的方式。而实例方法只有后面这种方式。比如以下:

     

  • 相关阅读:
    linux 下高精度时间
    pstack
    linux 调试常用命令
    定位 UNIX 上常见问题的经验总结
    在 POSIX 线程编程中避免内存泄漏
    ulimit
    设计模式之迭代器模式(PHP实现)
    设计模式之责任链模式(php实现)
    设计模式之代理模式(php实现)
    设计模式之享元模式(PHP实现)
  • 原文地址:https://www.cnblogs.com/somedayLi/p/7693067.html
Copyright © 2011-2022 走看看