为什么java构造函数的构造器只能在第一行写this() 或者super() ?

最近在看内部类, 但是被“为什么匿名内部类或者局部内部类使用方法的局部变量时, 局部变量一定得是final类型”困扰着, 在网上查找资料的时候, 发现我对类初始化完全不了解, 之前的认识都是错误! 所以回头又看了看基础的初始化, 在看初始化的时候, 就发现一点, 就是“为什么只能在构造器的第一行写this() 或者super()?” 我比较笨,又想了好久,上网查了下资料,看了看书才明白。

在说这个问题之前,首先得要明白super()和this()的意义:

  1. this() 之所以存在, 我个人认为原因很简单, 就是为了代码的复用(纯粹的个人观点, 不知道是否正确)
  2. super()之所以存在, 是有很重要的原因的! 因为子类与父类之间是继承关系, 而继承就意味着得到父类中所有的成员变量和方法. 既然能够得到父类的这些成员, 也就意味着子类可以访问父类的方法和成员变量(当然, 得到不意味着就可以任意使用, 使用的前提是必须是有相应的访问权限) , 如果子类在使用父类成员的时候, 父类内的成员变量没有得到正确的初始化, 那么就会发生意想不到的错误, 所以问题就出现在了这里, 如何保证父类成员是安全的呢? 这就得保证父类得到了正确的初始化, 而父类对象正确的初始化就离不开父类的构造函数, super存在的意义也正是如此. 在子类的构造函数中,如果没有显式使用super() , 并且第一行没有使用this()调用子类的构造函数, 那么编译器就会自动在第一行补齐super()来调用父类的默认构造函数, 如果父类没有默认的构造函数就会报错.

为什么一定要在第一行?

  super()在第一行的原因就是: 子类有可能访问了父类对象, 比如在构造函数中使用父类对象的成员函数和变量, 在成员初始化使用了父类, 在代码块中使用了父类等, 所以为保证在子类可以访问父类对象之前要完成对父类对象的初始化

  this()在第一行的原因就是: 为保证父类对象初始化的唯一性. 我们假设一种情况, 类B是类A的子类, 如果this()可以在构造函数的任意行使用, 那么会出现什么情况呢? 首先程序运行到构造函数B()的第一行, 发现没有调用this()和super(), 就自动在第一行补齐了super() , 完成了对父类对象的初始化, 然后返回子类的构造函数继续执行, 当运行到构造函数B()的"this(2) ;"时, 调用B类对象的B(int) 构造函数, 在B(int)中, 还会对父类对象再次初始化! 这就造成了对资源的浪费, 当然也有可能造成某些意想不到的结果, 不管怎样, 总之是不合理的, 所以this() 不能出现在除第一行以外的其他行!

当创建一个子类对象的时候, 该对象会包含一个父类的子对象, 不管你是否使用.

//thinking in java笔记,如果有不对的地方,还望指正^_^

时间: 2024-11-16 08:59:04

为什么java构造函数的构造器只能在第一行写this() 或者super() ?的相关文章

Java中的构造器

Java中的构造器 Java在使用new创建对象时,会调用其构造器,构造器与方法不同,其没有返回值,且其名字与类名一致,在构造器中,我们可以初始化类的一些fields,这样,当我们创建好对象后,这些对象都有了默认的初始值 . 当我们的类在继承父类的时候,在创建子类对象的时候,首先会调用父类的构造器,实际上,父类的构造器在调用之前,会继续调用Object类的构造器,当Object类的构造器调用完成之后,才调用父类的构造器,依次在调用子类的构造器.这样做的原因是,我们的子类对象的fields的值可能

Java 构造函数(抽象类中的构造函数) 和 加载

博客分类: 面向对象设计的原则 与 概念 1. Java 的构造函数 与初始化块: a. 抽象类的构造函数 若果在父类中(也就是抽象类)中显示的写了有参数的构造函数,在子类是就必须写一个构造函数来调用父类的构造函数 abstract class Person {   //定义一个抽象类,必须被继承 Person(int i) { } } public class Student extends Person { Student() { super(int i)://必须显示的调用父类构造方法//

Java面向对象之构造器

目录 Java面向对象之构造器 利用构造器确保初始化 构造器重载 Java面向对象之构造器 利用构造器确保初始化 初始化问题是关系编程方式是否安全的一个重要的问题. 功能:在创建对象时执行初始化. 在Java中,每个类至少有一个构造器.格式如下: [修饰符] 构造器名(参数列表){ ...执行体 } 这时,突然迷惑,之前写过的代码里都没有构造器的说法呀,是怎么回事呢? 先看下面的语句: Student s0 = new Student(); 这是我们之前经常写的,我们管他叫做创建对象,并让引用变

Java中是构造器创建对象吗?

首先,这里说明” Java中是构造器创建对象 “这句话是完全错误的. Java中构造器的作用主要是为了初始化变量的值...其实在执行构造器之前,Java对象所需要的内存空间,已经产生了... 一般可以理解为由new关键字创建出来的哦. 在某些时候,一般通过new 关键字创建出相应的对象后,可以通过对应的构造方法来初始化对应变量的值. 但在某些特殊情况下,我们可以不通过new关键字而创建出相关的对象 常见的两种不通过new 关键字创建对象的方式如下: 1)通过Java的序列化和反序列化,来创建相关

JAVA构造函数

一.什么是构造函数 java构造函数,也叫构造方法,是java中一种特殊的函数.函数名与相同,无返回值. 一般用来给对象进行初始化. 在现实生活中,很多事物一出现,就天生具有某些属性和行为.比如人一出生,就有年龄.身高.体重.就会哭:汽车一出产,就有颜色.有外观.可以运行等.这些,我们就可以将这些天然的属性和行为定义在构造函数中,当new实例化对象时,也就具有这些属性和方法了,没必要再去重新定义了,从而加快了编程效率. 构造函数是对象一建立就运行,给对象初始化. 而一般方法是对象调用才执行,是给

Java基础03 构造器与方法重载(转载)

显式初始化要求我们在写程序时就确定初始值,这有时很不方便.我们可以使用构造器(constructor)来初始化对象.构造器可以初始化数据成员,还可以规定特定的操作.这些操作会在创建对象时自动执行. 定义构造器 构造器(constructor)是一个方法.像普通方法一样,我们在类中定义构造器.构造器有如下基本特征: 构造器的名字和类的名字相同 构造器没有返回值 我们定义Human类的构造器: public class Test{    public static void main(String[

java构造函数修饰符

今天看了剑指offer中的第二章-面试需要的基础知识,对其中的一段C#面试代码,比较感兴趣,想着能否给改成java,结果没改成,出现了问题,本文是针对这一点来总结一下,下面是C#与java代码,但是在eclipse环境下,java代码如此改写,编译器提醒构造函数有问题,究其原因,问题是由java的构造函数前的访问修饰符public与特殊修饰符static所导致的. java 构造函数,可以被访问修饰符修饰,而不能被特殊修饰符修饰:(在编译器经过测试) 访问修饰符: public (最常用,其他类

Think in Java 构造函数_继承_super()_android_Dialog()_为何有些类没有构造函数自己体悟

首先是因为自己看到了去看了张龙老师的教程 里面说到关于 多态的一个很直观的体现就是:构造函数的不同 还有就是父类和子类之间的构造函数的调用关系 具体来说:子类继承父类,并且创建子类对象过程中 首先new 子类(无参)的过程之前有说过的(是没有继承的情况) 有继承的情况下,首先要执行调用子类的默认无参构造函数,执行里面的第一行语句:默认的隐式调用父类的默认的无参构造函数[觉得这句话不对,觉得应该是先加载的父类之后,可是怎么知道调用的就是父类的默认的无参构造函数呢?要是子类之命了是其他的构造函数,那

Java、JVM和操作系统之间的关系,写给新人,

来张图:这个帖子写给新人的,老玩家就直接无视他,因为这个完完全全是白话基础原理. 解释:上面的图是从上往下依次调用的关系. 操作系统(Windows/Linux)管理硬件,让硬件能够正常.合理的运行,当然各种硬件的驱动实现了操作系统的接口,操作系统调用这些接口就能管理硬件,操作系统还像程序员提供了一层接口,叫做系统呼叫层,程序员可以面向这一层的接口编程,来实现对计算机的控制,而不同的操作系统(或者说不同的CPU架构)所提供的接口都是不一样的,Windows和Linux提供给的那肯定是完全不一样的