`
Rejoy
  • 浏览: 205858 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

再论Java的构造方法

    博客分类:
  • java
 
阅读更多

在OOP语言中,都会有构造方法这个概念,它的主要作用就是用于创建一个类的实例,并为这个实例的成员变量赋值。虽然它是一个好像很简单的东西,但是好像还有很多人对它的理解还不是很透彻,往往在面试中就会搞一些比较2B的题目来考大家。

写这个主题主要是因为在自己的代码中出现了问题,在XStream中,它在实例化的时候是不会调用类的默认方法的,后面自己去跟了一下XStream的源码才发现,它是用了Unsafe中的allocateInstance方法来实例化的,而这个方法是不会去调用构造方法的,导致了Map cache = new HashMap();这个cache成员变量没有被赋值,最后用的时候就出现了NullPointerExption。

我猜这XStream是肯定没有调用类的默认构造方法,不然不可能会null的,结果就跟其他两个同事讨论起构造方法的事来,他们都说成员变量的赋值都是在构造方法之前执行的,而我说成员变量的初始化是在构造方法里面执行的。在论证这个之前,我们先来看一个比较误导人的命题:“当一个类没有定义任何构造方法时,编译器会生成一个什么都不做的默认构造方法”,我拿这个问题问了以前的同事,他竟然说这是对的,这段话好像在很多教材里面都会出现。这句话里的一半是对的,至于哪里错了,我们就要用事实来说话了。

先上一段简单的代码:

public class Test {

	int a = 100;

}

 

这段代码只有简单的三行代码,但是却已经可以证明上面那句话的问题了。首先这个类里面是没有任何构造方法的,为了证明上面那句话是有一半错误的,我们需要看编译器为我们生成了些什么东西。在这里我们需要用到javap命令,这个命令能为我们的class文件转成对应的字节码指令。

 

在这里我们看到,编译器确实帮我们生成了一个默认的构造方法,但是它是什么都不做的默认构造方法么?明显不是,生成好几行的字节码指令。那么,我们现在来看一下这些生成的字节码指令都做了些什么事,首先会将this压入栈中,接着调用父类的构造方法,最后为成员变量赋值。现在我们就可以得出两个结论了:1、编译器为我们生成的默认构造方法并不是什么都不做的”懒人“;2、类中的成员变量的赋值是放到构造方法中去的,而并不是在构造方法之前执行的。相当于生成了以下的代码:

 

public class Test {

	int a;
	
	Test()
	{
		super(); // 首先去调用父类的构造方法
		a = 100; // 为成员变量赋值
	}

}

    再来看一下构造方法里面的代码和成员变量赋值的顺序,再来一段简单的代码:

public class Test {

	int a = 100;
	
	int b = 200;

	Test() {
		int e = 300;
		int f = 400;
	}
	
	int c = 500;
	
	int d = 600;
}

 

   看了这段简单的代码后,大家先花几秒钟的时间来猜一下它们的执行顺序是怎么样的大笑

   国际惯例,我们用javap命令来看一下它生成的字节码指令(javap真是一个好用的东西啊,哈哈)

    看了这图之后,相信大家都已经知道答案了吧。相当于生成了以下的代码:

public class Test {

	int a;
	
	int b;

	Test() {
		a = 100;
		b = 200;
		c = 500;
		d = 600;
		int e = 300;
		int f = 400;
	}
	
	int c;
	
	int d;
}

 

   哈哈,我就不多费口舌了。希望这篇博客能帮到大家。

 

0
0
分享到:
评论

相关推荐

    Java构造方法解析.pdf

    下面详细解析Java构造方法的特性和使用方法。 构造方法的特性: 1. 方法名与类名相同:构造方法的名字必须与类名完全相同,这是Java语法规定的一部分,便于编译器识别并自动调用构造方法。 2. 构造方法无返回类型:...

    Java中构造方法的深入研究与探讨.pdf

    Java 中构造方法的深入研究与探讨 本文探讨了 Java 中构造方法的概念、特点和应用,通过对构造方法的深入研究和探讨,阐述了其在继承和设计模式中的重要作用。 知识点一:构造方法的概念和特点 构造方法是 Java ...

    论构造方法的方法论.zip

    在IT行业中,构造方法是面向对象编程中的一个关键概念,特别是在Java、C#等语言中。这个概念对于理解和实现类的实例化至关重要。"论构造方法的方法论.zip"的文件标题暗示了这是一个深入探讨构造方法设计策略的资源,...

    Java语言程序设计教学中构造方法的研究.pdf

    Java语言是一种面向对象的编程语言,在面向对象编程中,对象的创建是通过构造方法来实现的。构造方法是一种特殊的成员方法,它的名称与类名完全相同,并且没有返回值类型,连void都没有。构造方法在对象实例化的过程...

    Java编程方法论 之 Spring Reactor Reactor-Netty Spring Webflux 全面解读.pdf

    Java编程方法论中,Spring Reactor、Reactor-Netty和Spring Webflux是现代Java开发中用于构建反应式应用程序的关键组件。Spring Reactor是响应式流(Reactive Streams)规范的实现,它提供了用于处理异步事件和数据...

    一种基于UML关系的Java代码库构造方法.pdf

    3. 文档中提出了一种基于UML关系的Java代码库构造方法。这种方法的核心在于使用图数据库作为实现平台,并以抽象语法树(AST)为基础来构建图结构。 二、图数据库与抽象语法树 1. 图数据库是一种特殊的数据库,它...

    一种基于UML关系的Java代码库构造方法.zip

    本资源"一种基于UML关系的Java代码库构造方法"探讨了如何利用UML的关系来指导Java代码的生成,从而构建高效、结构化的代码库。以下是对这个主题的详细解释: 1. **UML简介**:UML是面向对象设计的一种标准化语言,...

    连连看java程序代码,也能用论文

    `AnimateDelete`类提供了几个构造函数,用于根据不同的情况初始化消除路径。例如,`AnimateDelete(int direct, Point a, Point b)`用于处理两个点之间的直线消除,`AnimateDelete(int direct, Point a, Point b, ...

    论C#与Java之异同

    ### 论C#与Java之异同 #### 引言 Dare Obasanjo撰写的这篇详尽且精准的文章——《论C#与Java之异同》首次发布于2001年,随着时间的推移,它已经成为了一个比较这两门语言的权威资料。基于C# 2.0和Java SE 6的新...

    JAVA课程设计(含源代码源程序以及论文)

    Java课程设计是一个重要的实践环节,它旨在让学生深入理解Java编程语言的原理,提高编程技能,并锻炼问题解决能力。这份资源包含完整的源代码、源程序和论文,为学习者提供了全面的学习材料,可以从多个角度深入了解...

    论JAVA继承机制中父类与子类的关系

    ### 论JAVA继承机制中父类与子类的关系 #### 摘要 本文深入探讨了Java语言中的继承机制,并重点分析了父类与子类之间的关系。文章围绕子类继承父类成员的过程、成员变量及方法的赋值、重写、覆盖等问题展开讨论,...

    语义网 java 范畴论小论文

    【语义网、Java、范畴论】在计算机科学中,特别是Java编程语言的面向对象设计中,范畴论的概念被用来理解和构建复杂的抽象概念。范畴论是一种数学理论,它抽象出数学对象之间的关系,形成一种通用的语言,使得不同...

    浅析使用模型参数构造Java Swing组件.pdf

    在构造Java Swing组件时,经常使用参数的构造方法来完成。为了实现代码的封装和重用,可以通过继承相关的类来构建组件。例如,下拉列表框(ComboBox)和列表框(ListBox)是Swing中的常见组件,它们都具有多个构造...

    java基础理论论习题

    通过"Java初学者习题20道.doc",你可以深入实践这些方法的运用。 5. **面向对象编程** Java是面向对象的语言,因此封装、继承和多态是其核心特性。习题中可能包含创建类、对象,理解构造器,以及实现继承和接口的...

    JAVA小论文(浅谈String类)

    Java提供了多种方式来创建字符串,例如使用字符串字面量、使用String类的构造方法等。Java也提供了多种方式来比较字符串,例如使用equals()方法、compareTo()方法等。 Java中的字符串替换可以使用replaceAll()方法...

    Java中this与super关键字的对比使用.pdf

    如果没有在子类中显式地调用super(),Java虚拟机会默认调用父类的无参构造方法。如果父类中没有无参构造方法,子类的构造方法中必须显式调用带参的父类构造方法。 本文档通过分析this与super关键字的基本用法,明确...

    JAVA本地监听与远程端口扫描(源代码+论文).zip

    开发者可以通过调用`ServerSocket(int port)`构造方法来创建一个监听特定端口的服务器,然后使用`accept()`方法等待并接受客户端的连接。这是一个被动的过程,因为服务器等待客户端的主动连接。 远程端口扫描则涉及...

    JAVA的重载和覆盖(论文)

    构造方法重载是重载的一种特殊情况,指的是在一个类中可以有多个构造方法,每个构造方法可以接受不同类型的参数,这样就可以根据不同的需求初始化对象。构造方法重载可以提供更加灵活的实例化机制,满足不同的初始化...

    关于JAVA8 Window类的使用方法.pdf

    一个常见的构造方法是Window(Frame owner),它允许你创建一个新的窗口,并将一个已存在的Frame对象作为它的所有者。如果当前没有指定所有者,或者所有者已经隐藏或关闭,则此方法会抛出一个IllegalArgumentException...

Global site tag (gtag.js) - Google Analytics