“==”符的注意事项、类的构造与使用、静态初始块的执行顺序

一、==符的使用

问题:

观察以下代码,两对整数明明完全一样,为何一个输出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关键字的字段或方法)?

解决方法:

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

 

 

posted @ 2017-10-19 16:06  Someday&Li  阅读(393)  评论(0编辑  收藏  举报