1-从继承的角度来看,将构造函数声明为私有会有何作用?(第 93 页)

解法

将构造函数声明为私有(private),可确保类以外的地方都不能直接实例化这个类。在这种 情况下,要创建这个类的实例,唯一的办法是提供一个公共静态方法,就像工厂方法模式(Factory Method Pattern)那样。

此外,由于构造函数是私有的,因此这个类也不能被继承。

2-在Java中,若在try-catch-finally的try语句块中插入return语句,finally语句 块是否还会执行?(第 93 页)

解法

是的,它会执行。当退出try语句块时,finally语句块将会执行。即使我们试图从try语句 块里跳出(通过return语句、continue语句、break语句或任意异常),finally语句块仍将得以 执行。 注意,有些情况下finally语句块将不会执行,比如:

  •  如果虚拟机在try/catch语句块执行期间退出;
  •  如果执行try/catch语句块的线程被杀死终止了。

3-final、finally和finalize之间有何差异?(第 93 页)

解法

尽管名字相像、发音类似,final、finally和finalize的功能截然不同。非常笼统地说,

  • final用于控制变量、方法或类是否“可更改”。

  • finally关键字用在try/catch语句块中,以确 保一段代码一定会被执行。

  • 一旦垃圾收集器确定没有任何引用指向某个对象,就会在销毁该对象 之前调用finalize()方法。

下面是关于这几个关键字和方法的更多细节。

  1. final 上下文不同,final语句含义有别。

 应用于基本类型(primitive)变量时:该变量的值无法更改。

 应用于引用(reference)变量时:该引用变量不能指向堆上的任何其他对象。

 应用于方法时:该方法不允许重写。

 应用于类时:该类不能派生子类。

  1. finally 在try块或catch块之后,可以选择加一个finally语句块。finally语句块里的语句一定会 被执行(除非Java虚拟机在执行try语句块期间退出)。我们会在finally语句块里编写资源回收 和清理的代码。

  2. finalize() 当垃圾收集器确定再无任何引用指向某个对象实例时, 就会在销毁该对象之前调用 finalize()方法,一般用于清理资源,比如关闭文件。

4-14.4 C++模板和Java泛型之间有何不同?(第 93 页)

解法

许多程序员都认为模板(template)和泛型(generic)这两个概念是等价的,因为两者都允 许你按照List<String>的样式编写代码。不过,各种语言是怎么实现该功能的,以及为什么这 么做,却千差万别。 Java泛型的实现植根于“类型消除”这一概念。当源代码被转换成Java虚拟机字节码时,这 种技术会消除参数化类型。

有了Java泛型,我们可以做的事情也并没有真正改变多少;它只是让代码变得漂亮些。鉴于 此,Java泛型有时也被称为“语法糖”。

这点跟C++的模板截然不同。在C++中,模板本质上就是一套宏指令集,只是换了个名头, 编译器会针对每种类型创建一份模板代码的副本。

由于架构设计上的差异,Java泛型和C++模板还有如下很多不同点。

  •  C++模板可以使用int等基本数据类型。Java则不行,必须转而使用Integer。
  •  在Java中,可以将模板的类型参数限定为某种特定类型。例如,你可能会使用泛型实现CardDeck,并规定类型参数必须扩展自CardGame。  在C++中,类型参数可以实例化,但Java不支持。
  •  在Java中,类型参数(即MyClass<Foo>中的Foo)不能用于静态方法和变量,因为它们会被MyClass<Foo>和MyClass<Bar>所共享。在C++中,这些类都是不同的,因此类型参数可以用于静态方法和静态变量。
  •  在Java中,不管类型参数是什么,MyClass的所有实例都是同一类型。类型参数会在运行时被抹去。在C++中,参数类型不同,实例类型也不同。

Object类常用方法

toString() clone() wait() notify()
notifyAll() hashcode() equals() finallize()

重写equals()和hashcode()方法

​ 默认情况下也就是从超类Object继承而来的equals方法与‘==’是完全等价的,比较的都是对象的内存地址,但我们可以重写equals方法,使其按照我们的需求的方式进行比较,如String类重写了equals方法,使其比较的是字符的序列,而不再是内存地址。

重写equals()需要符合以下规则:

  • 自反性 。对于任何非null的引用值x,x.equals(x)应返回true。
  • 对称性 。对于任何非null的引用值x与y,当且仅当:y.equals(x)返回true时,x.equals(y)才返回true。
  • 传递性 。对于任何非null的引用值x、y与z,如果y.equals(x)返回true,y.equals(z)返回true,那么x.equals(z)也应返回true。
  • 一致性 。对于任何非null的引用值x与y,假设对象上equals比较中的信息没有被修改,则多次调用x.equals(y)始终返回true或者始终返回false。

对于任何非空引用值x,x.equal(null)应返回false。

重写equals()的同时需重写hashCode()

java中,可以使用hashCode()来获取对象的哈希码,其值就是对象的存储地址,这个方法在Object类中声明,因此所有的子类都含有该方法。

在Java API文档中关于hashCode方法有以下几点规定:

  • 在java应用程序执行期间,如果在equals方法比较中所用的信息没有被修改,那么在同一个对象上多次调用hashCode方法时必须一致地返回相同的整数。如果多次执行同一个应用时,不要求该整数必须相同。
  • 如果两个对象通过调用equals方法是相等的,那么这两个对象调用hashCode方法必须返回相同的整数。
  • 如果两个对象通过调用equals方法是不相等的,不要求这两个对象调用hashCode方法必须返回不同的整数。但是程序员应该意识到对不同的对象产生不同的hash值可以提供哈希表的性能。

results matching ""

    No results matching ""