关于java核心技术(卷一)读后的思考(回调,clone的讨论)

zzuzhouxiang      2022-04-27     299

关键词:

回调

回调是一种常见的程序设计模式。这种模式中,可以指出某个特定事件发生时应该采取的动作。

直接给上代码

package com.java.timer;

import java.awt.event.ActionListener;

import javax.swing.JOptionPane;
import javax.swing.Timer;

public class TimerTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ActionListener listener=new TimePrinter();
        Timer t = new Timer(10000,listener);
        t.start();
        JOptionPane.showMessageDialog(null, "Quit program?");
        System.exit(0);
        

    }

}
package com.java.timer;

import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;

public class TimePrinter implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent event) {
        // TODO Auto-generated method stub
        System.out.println("At the tone,the time is "+new Date());
        Toolkit.getDefaultToolkit().beep();
    }

}

这里调用了java.swing包中的Timer类,可以使用它在给定的时间间隔时发出通告

我们这里可以分析下这段代码。构造一个TimePrinter类调用ActionListener接口,而这个类对这个方法的实现,是通过构造Date对象,紧接着调用静态方法deep()进行提示。

 ActionListener listener=new TimePrinter();
这个语句的意思是声明一个接口类型的变量,然后new一个TimePrinter对象。利用接口型变量对其存储。

紧接着利用Timer方法构造一个定时器,调用接口变量为其中之一的参数,最后调用JOptionPane()方法来构造一个对话框,整个过程就完成了。

这个过程就体现出了回调这个设计模式的思想。在后面的博客中我应该会总结Java的设计模式。

 

对象克隆

这里要说到对象克隆的知识了。这里我们就会讨论一个Cloneable接口,这个接口只是一个类提供了一个安全的clone()方法。

这里可以举个例子,

Employee original = new Employee("John Public",50000);
Employee copy =original;
copy.raiseSalary(10);

我们来分析一下这段代码,第一句new了一个Employee对象,将对象存储地址保存在original中,而第二句则将original中存储的对象复制了一份到copy变量中去了,这样的话original和copy指向的都是同一个地址,也就是那个实例地址存储在这两个变量中,所以第三句对copy进行修改,同时也对original进行修改了。

而我们希望拷贝一份与原来无关的变量,那这样就要用到clone方法了。

Employee original = new Employee("John Public",50000);
Employee copy = original.clone();
copye.raiseSalary(10);

clone方法是Object的一个protect方法,说明代码不能直接调用这个方法,只有子类或者相同的类才可以克隆父类对象。这个限制是有原因的,我们可以从Object如何实现clone方法来想。因为其对这个对象是一无所知的,只能逐个域的进行拷贝。

这里我们就要讨论一下clone的分类:

它分为深拷贝浅拷贝

默认的克隆操作是“浅拷贝”,浅拷贝有什么影响,是要看具体情况的,如果原对象和浅克隆对象共享的子对象是不可变的,那么这种共享就是安全的。如果子对象属于一个不可变的类,如String,简而言之,就是所有的量不可改变的量是,浅拷贝是安全的。如果存在可变的量,就要对clone方法建立一个深拷贝。

对于每一个类,需要确定:

1)默认的clone方法是否满足要求;

2)是否可以在可变的子对象上调用clone来修补clone方法;

3)是否不该使用clone;

如果一个对象请求克隆,但并没有实现这个接口,就会生成一个受查异常。Cloneable接口是Java提供的一组标记接口之一,正常接口一般是确保一个类实现一个或一组特定的方法。标记接口不包含任何方法,它唯一的作用是允许在类型查询中使用instanceof。即使浅拷贝实现能满足要求,但还是要实现Cloneable接口,将clone重新定义为public,再调用super.clone()。

代码:

class Employee implements Cloneable
{
public Employee clone() throws CloneNotSupportedException
{
return (Employee)super.clone();
}
……}

与Object.clone提供的浅拷贝相比,前面看到的方法并没有增加任何功能,只是将其设为公有的。要建立深拷贝,需要更多工作,克隆对象中可变的实例域。

下面是一个例子:

class Employee  implements Cloneable
{
……
   public Employee clone() throws CloneNotSupportedException
  {
     Employee cloned =(Employee) super.clone();
     Cloned.hireDay=(Date)hireDay.clone();
     return cloned;
   }
}

如果都在一个对象上调用clone,但这个对象的类并没有实现Cloneable,这个clone方法就会抛出一个异常。虽然Employee和Date类实现了Clone接口,但是编译器并不知道,所有直接throws这个异常。

这里要注意一个问题,就是子类的克隆,假设我们已经定义了Employee类的clone方法,这时候,就要知道,任何人都会用它来克隆Manager,这时候就要取决于Manager的域了,如果增加的域都是基本数据类型或者是不可变类,那就没有问题,如果不是的话,那就需要重新定义clone方法。

 

总而言之,其实很简单,浅拷贝就是默认拷贝,不需要克隆对象中的可变实例域,只需要将clone方法定义为public类型就可以了

深拷贝就是需要重新定义clone()方法,使可变类实现拷贝,两者都要对其进行异常处理。

 

关于java核心技术(卷一)读后的思考(equals方法的讨论)

这是我反复看了两遍才理解的部分。其中也不乏参考了他人的微博内容,才大致对这个方法有所理解。首先我们从Object类开始说起,书中已经说了Object类是Java中所有类的始祖,在Java中的每个类都是由他扩展而来的,但在现实使... 查看详情

关于java核心技术(卷一)读后的思考(泛型数组列表的讨论)

在C++中编译时是要确定数组大小的,而Java有所不同,它允许在运行时确定数组的大小。但是如果仅通过数组是无法改变运行时无法动态更改数组的问题。一旦确定了数组大小,就很难改变他了数组的大小了,要解决这个问题,... 查看详情

关于java核心技术(卷一)读后的思考(用户自定义类,静态域和静态方法的思考以及方法参数)

用户自定义类:这部分并没有太过于困难的部分,借由代码进行复习:Employee类的定义:packagecom.java.EmployeeTest;importjava.time.*;publicclassEmployee{   privateStringname;   privatedoublesalary;  &nb 查看详情

关于java核心技术(卷一)读后的思考(接口的基本知识的讨论)

接口接口技术:这种技术主要用来描述类具有什么功能,而并不给出每个功能的具体实现。一个类可以实现一个或多个接口,并在需要接口的地方,随时使用实现了相应接口对象。接口概念:接口不是类,而是对类的一组需求的... 查看详情

关于java核心技术(卷一)读后的思考(对象与类,日历的构造)

关于这本书,前三张都是基本内容,我觉得个人掌握的还可以,所以从第四章开始整理每日所学。第四章主要说的是对象和类。第一部分是面向对象程序设计的概述。其中面向对象程序设计简写OOP,接下来写的是类,即构造对象... 查看详情

关于java核心技术(卷一)读后的思考(lambda表达式的讨论)

lambda表达式lambda表达式是一个可传递的代码块。可以以后执行一次或者多次。在程序运行中我们经常会遇到传递代码段的情况,但是我们一般都是先构造一个对象,然后通过对象调用相应的代码块来实现传递代码块的目的,这个... 查看详情

《java核心技术(卷一)》读书笔记——第六章:内部类

1.      内部类的概念?类中类2.      为什么要用内部类?内部类的方法可以访问外部类的实例域内部类对外部类的同一个包中的类实现了隐藏匿名内部类在“想要定义一个回调函数却... 查看详情

《java核心技术卷一》随笔

1.静态常量:  静态变量使用得比较少,但静态常量使用得比较多,例如,在Math类中定义了一个静态常量:  publicstaticfinalPI=3.141592653;  在程序中,可以采用Math.PI的形式获得这个常量。  如果关键字static被省略,PI就变... 查看详情

java核心技术卷一笔记7

第九章集合9.1Java集合框架在Java类库中,集合类的基本接口是Collection接口。访问集合元素时,使用“foreach”循环编译器会将其翻译成带有迭代器的循环。元素被访问的数据取决于集合类型,对于ArrayList进行迭代就会按顺序得到... 查看详情

java核心技术卷一笔记8

第十四章并发多进程和多线程的区别:每个进程拥有自己的一套变量,而线程共享数据。14.1什么是线程不要调用Thread类或Runnable对象的run方法。直接调用run方法只会执行同一个线程中的任务,而不会启动新线程。应该调用start方... 查看详情

java核心技术卷一笔记六date类

在Java核心技术卷就行了一前期 date类出现的频率很高 所以就对date类进行了小小的整合Date类有两个date类表示特定时间的类 这个构造函数分配一个Date对象并初始化它代表指定的毫秒数,因为被称为“纪元”,即1970年1... 查看详情

go语言核心技术(卷一)之2.1-整数

第二章序 在计算机底层,一切都是比特位。然而计算机一般都操作固定大小的数,称之为字(word)。字会被解释为整数、浮点数、比特位数组、内存地址等,这些字又可以进一步聚合成数据包(packet)、像素点、作品集、是个或者... 查看详情

面霸篇:高频java基础问题(核心卷一)(代码片段)

从面试题作为切入点提升大家的Java内功,所谓根基不牢,地动山摇。只有扎实的基础,才是写出写好代码。拒绝知识碎片化码哥在《Redis系列》的开篇Redis为什么这么快中说过:学习一个技术,通常只接触了零... 查看详情

《大型网站技术架构:核心原理与案例分析》读后感

 李智慧的著作《大型网站技术架构:核心原理与案例分析》,写得非常好, 本着学习的态度,对于书中的关于性能优化的讲解做了一个思维导图,供大家梳理思路和学习之用。抛砖引玉。   查看详情

左耳朵耗子关于技术变现一文读后感

核心论点我完全没有必要通过打工听人安排而活着,而是反过来通过在公司工作提高自己的技能,让自己可以更为独立和只有地生活如何技术变现保持学习,掌握大多数人不能掌握的技能,先让周围的人有求于我关注有价值的东... 查看详情

《构建之法》第十六章读后感更正

第十六章IT行业的创新1.关于灵感。灵光闪现固然重要,很多伟大的发明依靠的就是灵光一现的基础,但是灵光闪现的前提是个人的思考,长时间的思考。完成这一灵光的基础是不断的尝试,提高自己的技术。这样才会将自己的... 查看详情

《java核心技术》读后感(java小虚竹)

❤️作者主页:小虚竹❤️作者简介:大家好,我是小虚竹。Java领域优质创作者🏆,CSDN博客专家🏆,华为云享专家🏆,掘金年度人气作者🏆,阿里云专家博主🏆❤️技术活,该赏... 查看详情

读书列表

 记录读书列表,促进阅读~蓝血十杰2017-04-20百年孤独(英文版)ThinkinginC++(英文版)卷一2017-04-26ThinkinginC++(英文版)卷二ReadingCodeJava核心技术卷一Java核心技术卷二重构    查看详情