阅读《effective java-第17条》遇到的问题解决与分享
问题背景
最近这2天准备重新看一遍《effective java》,发现这些经典的书籍真的是看一遍又有一遍的感受。也越来越觉的学习的过程是一个重复的过程。这次遇到的问题是在第17条中看到的,看了蛮久都没有看懂视例代码。第17条的内容是要么为继承而设计,并提供文档说明,要么就禁止继承。在其中有一段示例构造器决不能调用可被覆盖的方法代码如下:
父类代码
package com.sitech.test;
/**
* effect of java
* @author liaowp
*
*/
public class Super { public Super(){
overrideMe();
} public void overrideMe(){ }
}
子类代码
package com.sitech.test; import java.util.Date; /**
* effect of java
* @author liaowp
*
*/
public class Sub extends Super{
private final Date date; Sub(){
date =new Date();
} @Override
public void overrideMe(){
System.out.println("时间"+date);
} public static void main(String[] args) {
Sub sub = new Sub();
sub.overrideMe();
}
}
输出结果:

你可能会期待这个程序会打印出日期两次,但是它第一次打印的是null,因为overrideMe方法被super构造器调用的时候,构造器Sub还没有机会初始化date域。注意,这个程序观察到的final域处于2种不同的状态。还要注意,如果overrideMe已经调用了date中的任何方法,当Super改造器调用overrideMe的时候,调用就会抛出NullPointerException异常(原文)。
问题提出
看到很多的人看到上面的代码都会知道结果,但是我当时却卡在了为啥父类构造方法调用overrideMe是子类的?瞬间懵了,当时没有理解过来。脑子转不过来了,只能查查资料了,但是不知道怎么搜索。于是只能自己瞎折腾一下。于是先把代码加上打印:

问题解决
确实是调用的子类的overrideMe方法,还是不太懂。只能debug了,在debug之前我又在overrideMe方法加上了一个this,我想看看this代表的是谁。


debug之后可以看到this指的是Sub,date是空的,这样知道就知道父类的构造方法中调用的overrideMe是那里的,所以也就明白了父类为啥调用的是子类的方法了。main里面就是实例化了子类,this代表的就是子类,所以父类中构造方法中调用overrideMe的就是子类的overrideMe。完美
问题总结与分享
人有时候容易思维定势,导致有时候别人很容易看出的问题自己一直懵在里面出不来,这个问题对于我来说就是这样的额,自己当时怎么都搞不懂,固定在一个地方了,问了朋友问了导师,瞬间就想清楚了在经过自己的验证,问题就是找到答案了。虽然固定在那是痛苦的,不过找到问题答案就是开心的。
最近一直看资料看书,看到一段个人觉的非常不错的代码的分享给所有人。我们经常会看到字符串倒转的面试题,有很多实现方式,我就把自己看到的比较好的方式分享出来,这个方式也感觉跟我上面那个思维问题有点类似的感觉,个人感觉遇到字符串的倒转的问题的时候,很多会想到循环什么的。这个方法却出乎意料。代码如下:
 public static String reverse(String originStr) {
            if(originStr == null || originStr.length() <= 1)
                return originStr;
            return reverse(originStr.substring(1)) + originStr.charAt(0);//截取前面的补到后面去
}
阅读《effective java-第17条》遇到的问题解决与分享的更多相关文章
- Effective java第17条:要么为继承而设计,并提供文档说明,要么就禁止继承
		
不要过度设计. 面向对象编程,从一开始被洗脑难免在上手写代码时都会首先思考有没有公共方法啊,能不能把两个类抽象成一个父类再继承啊等,慎重使用继承,当要使用继承时一定要在文档注释中写明重写这个方法会给其 ...
 - 阅读《Effective Java》每条tips的理解和总结(1)
		
<Effective Java>这本书的结构是90来条tips,有长有短,每条tip都值的学习.这里根据对书中每条tip的理解做简短的总结,方便日后回顾.持续更新~ 1. 考虑用静态方法代 ...
 - 阅读《Effective Java》每条tips的理解和总结(2)(持续更新)
		
15. 使类和成员的可访问性最小化 一个好用的类的属性必须要隐藏起来,干净的将它与类的api分离开来,类之间只通过api相互使用,降低他们之间的耦合性.为了做到这一点,建议根据情况选择尽可能低的访问级 ...
 - Effective.Java第34-44条(枚举)
		
34. 使用枚举类型替代整型常量 常量的语义表达不清晰,只能靠前面的名称来区分.枚举具有可读性.更安全.更强大等优势.而且枚举类型对象之间的值比较可以使用==来比较值是否相等的,不是必须使用equa ...
 - Effective.Java第12-22条
		
12. 始终重写toString()方法 如果不重写toString()方法,打印的时候是 类名+@+哈希码的无符号十六进制.我们查看 Object的toString()方法如下: public S ...
 - Effective.Java第67-77条(异常相关)
		
67. 明智审慎地进行优化 有三条优化的格言是每个人都应该知道的: (1)比起其他任何单一的原因(包括盲目的愚钝),很多计算上的过失都被归咎于效率(不一定能实现) (2)不要去计算效率上的一些小小的 ...
 - Effective.Java第56-66条(规范相关)
		
56. 为所有已公开的API元素编写文档注释 要正确地记录API,必须在每个导出的类.接口.构造方法.方法和属性声明之前加上文档注释.如果一个类是可序列化的,还需要记录它的序列化形式. 文档注释在源 ...
 - Effective.Java第45-55条(规范相关)
		
45. 明智谨慎地使用Stream 46. 优先考虑流中无副作用的函数 47. 优先使用Collection而不是Stream作为方法的返回类型 48. 谨慎使用流并行 49. 检查参数有效 ...
 - Effective.Java第23-33条(泛型相关)
		
23. 类结构层次优于标签类 有时你会碰到一个类,它的实例有一个或多个风格,并且包含一个tag属性表示实例的风格.例如,如下面的类表示一个圆或者矩形: public class Figure { / ...
 - Effective.Java第1-11条
		
1. 考虑使用静态工厂方法替代构造方法 一个类可以提供一个公共静态工厂方法,它只是返回类实例的静态方法.例如JDK的Boolean的valueOf方法: public final class Bool ...
 
随机推荐
- CSS禁止Chrome谷歌浏览器激活输入框后自动添加橘黄色边框
			
Chrome默认会为所有的输入框加上橘黄色的边框,虽然有时候可以使我们的网站看起来更友好,但对自定义的样式是有影响的.当鼠标点击输入框时,在谷歌chrome浏览器中,光标移到输入框时激活输入框会被加上 ...
 - 使用cvs或svn从sourceforge上获取开源项目的方法[转载]
			
著名开源软件网站(www.sourceforge.net)上面的开源项目,大部分使用的管理工具为cvs或svn. 这两种软件的代表客户端程序是wincvs和tortoiseSVN. 1.cvs C ...
 - html meta标签用法详细介绍
			
meta是html语言head区的一个辅助性标签. 在页面中都有类似这样的html代码: <head> <meta http-equiv="content-Type&quo ...
 - 学习python网络数据采集笔记-1、2章
			
英文不好只能看中文版的.邮电出版社翻译的真很烂. 以上是吐槽,以下是正文. 书中用的pthon 3.X版本,建议安装python3.4以上的版本,低版本的没有自带pip安装插件会比较麻烦. 下载地址: ...
 - 【原创】Mvc学习笔记(1)
			
1.新建MVC4项目 在MVC4中有App_Data文件夹,这个文件夹里可以放一些重要的数据,比如说数据库的mdf文件等等,这个文件夹非常安全,因为这个文件夹不允许被别人下载,不允许被浏览器访问. A ...
 - Newtonsoft post Json 日期格式处理
			
Newtonsoft.Json.Converters.IsoDateTimeConverter DateTimeConverter = new Newtonsoft.Json.Converters. ...
 - nvarchar类型自动增长
			
,Col AS 'XH' + RIGHT('0000' + RTRIM(ID),4)
 - 修改tabbar 字体颜色
			
NSDictionary *seletedTextAttrs = @{NSForegroundColorAttributeName:[UIColor orangeColor]}; 修改tabbar 字 ...
 - 从零到一:caffe-windows(CPU)配置与利用mnist数据集训练第一个caffemodel
			
一.前言 本文会详细地阐述caffe-windows的配置教程.由于博主自己也只是个在校学生,目前也写不了太深入的东西,所以准备从最基础的开始一步步来.个人的计划是分成配置和运行官方教程,利用自己的数 ...
 - c/c++动态分配内存和malloc的使用
			
c/c++动态分配内存 为什么需要动态分配内存 ---很好的解决的了传统数组的4个缺陷 动态内存分配举例 ---动态数组的构造 使用动态数组的优点: 1. 动态数组长度不需要事先给定: 2. ...