为什么java构造函数的构造器只能在第一行写this() 或者super() ?
最近在看内部类, 但是被“为什么匿名内部类或者局部内部类使用方法的局部变量时, 局部变量一定得是final类型”困扰着, 在网上查找资料的时候, 发现我对类初始化完全不了解, 之前的认识都是错误! 所以回头又看了看基础的初始化, 在看初始化的时候, 就发现一点, 就是“为什么只能在构造器的第一行写this() 或者super()?” 我比较笨,又想了好久,上网查了下资料,看了看书才明白。
在说这个问题之前,首先得要明白super()和this()的意义:
- this() 之所以存在, 我个人认为原因很简单, 就是为了代码的复用(纯粹的个人观点, 不知道是否正确)
- 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笔记,如果有不对的地方,还望指正^_^
为什么java构造函数的构造器只能在第一行写this() 或者super() ?的更多相关文章
- Java 构造函数(抽象类中的构造函数) 和 加载
博客分类: 面向对象设计的原则 与 概念 1. Java 的构造函数 与初始化块: a. 抽象类的构造函数 若果在父类中(也就是抽象类)中显示的写了有参数的构造函数,在子类是就必须写一个构造函数来 ...
- Java面向对象之构造器
目录 Java面向对象之构造器 利用构造器确保初始化 构造器重载 Java面向对象之构造器 利用构造器确保初始化 初始化问题是关系编程方式是否安全的一个重要的问题. 功能:在创建对象时执行初始化. 在 ...
- Java 类的构造器中this()和super()的困惑
关于构造器中super的使用,书本上这样写: “super是指向父类的引用,如果构造方法没有显示地调用父类的构造方法,那么编译器会自动为它加上一个默认的super()方法调用.如果父类由没有默认的无参 ...
- 一文了解 Java 中的构造器
摘要:Java 也采用了构造器,并且还提供了一个垃圾收集器(garbage collector),当不再使用内存资源的时候,垃圾收集器会自动将其释放. 本文分享自华为云社区<一文带你了解 Jav ...
- Java文件中为什么只能有一个public修饰的类, 并且类名还必须与文件名相同
当编写一个java源代码文件时,此文件通常被称为编译单元(有时也被称为转译单元).每个编译单元都必须有一个后缀名.java,而在编译单元内则可以有一个public类,该类的名称必须与文件的名称相同(包 ...
- java.sql.Exception:setString 只能处理少于 32766 个字符的字符串
java.sql.Exception:setString 只能处理少于 32766 个字符的字符串 解决方式是 : 升级ojdbc的版本, 将原来的 ojdbc14_10.2.0.2.0.jar ...
- java构造函数修饰符
java 构造函数,可以被访问修饰符修饰,而不能被特殊修饰符修饰:(在编译器经过测试) 访问修饰符: public (最常用,其他类的任何位置都可以访问) protected(能够在同一包中被子类访问 ...
- Java中的构造器与垃圾回收
构造器 在我们初始化对象时,如果希望设置一些默认值,那么就可以使用构造器,在Java中,构造器使用和类同名的名字且没有返回值,如下 class Test{ private String name; T ...
- JAVA构造函数(方法)
一.什么是构造函数 java构造函数,也叫构造方法,是java中一种特殊的函数.函数名与相同,无返回值. 作用:一般用来初始化成员属性和成员方法的,即new对象产生后,就调用了对象了属性和方法. 在现 ...
随机推荐
- MySQL安装示例数据库
MySQL安装示例数据库 本文档演示如何下载及安装MySQL示例数据库sakila及employees数据库 1. 安装sakila数据库 1.1 下载sakila数据库 wget http://do ...
- 周期性任务计划: Crontab
文中部分内容摘自骏马金龙的博客,查看可点击 1. crontab简述 crontab命令用于周期性的执行任务,想要执行这个命令,需要首先启动crond(守护进程)服务才行 crontab是配置管理cr ...
- C语言学习9
婚礼的谎言 三对情侣参加婚礼,三个新郎为A.B.C,三个新娘为X.Y.Z.有人想知道究竟水域谁结婚2,于是就问新人中的三位,得到结果如下:A说他将和X结婚:X说她的未婚夫是C:C说他将和Z结婚.这人事 ...
- openstack创建虚拟机之后使用ssh登陆的解决办法
创建一个虚机之后:若果想要在horizon的控制台上登录操作,第一步.需要先使用ssh从controller上修改密码 从controller上登录: ssh ubuntu@虚机ip sudo su ...
- Task(TPL)简单的实现Winform(WPF)异步
很多时候,我们要实现Winform异步操作,你可以用传统的方法,但个人感觉代码不好理解,而且使用真有点不舒服.也可以用Task来实现,Task(.net4.0新添加的对象)其实就是对线程池线程的一个封 ...
- python接口自动化-发xml格式post请求
前言 post请求相对于get请求多一个body部分,body部分常见的数据类型有以下四种(注意是常见的,并不是只有4种) application/x-www-form-urlencoded appl ...
- 【转载】CentOS6.5升级手动安装GCC4.8.2
一.简易安装 操作环境 CentOS6.5 64bit,原版本4.4.7,不能支持C++11的特性~,希望升级到4.8.2 不能通过yum的方法升级,需要自己手动下载安装包并编译 1.1 获取安装包并 ...
- zoj 2807 Electrical Outlets
Electrical Outlets Time Limit: 2 Seconds Memory Limit: 65536 KB Roy has just moved into a new a ...
- [BZOJ2120][BZOJ2453]数颜色
[BZOJ2120]数颜色 试题描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中 ...
- [luoguP2216] [HAOI2007]理想的正方形(二维单调队列)
传送门 1.先弄个单调队列求出每一行的区间为n的最大值最小值. 2.然后再搞个单调队列求1所求出的结果的区间为n的最大值最小值 3.最后扫一遍就行 懒得画图,自己体会吧. ——代码 #include ...