I am with Joshua Bloch Email Discussion (Emails Between Joshua Bloch and Me)

xiaoxiao2021-03-06  179

Here Are Some Email Between Me and Joshua Bloch. I Hope these email will do some help for you. The Some Mail Had Been Saved for Some Time. I Think I Can Share Them with you.

About Joshua Bloch, Here Is Some Information:

Joshua Bloch, a senior staff engineer at Sun Microsystems, Inc. Bloch, an architect in the Core Java Platform Group, designed and implemented the award-winning Java Collections Framework, the java.math package, and has contributed to many other parts of the platform. The author of numerous articles and papers, Bloch has also written a book, Effective Java Programming Language Guide, which won the prestigious Jolt Award from Software Development Magazine. Bloch holds a Ph.D. in computer science from Carnegie-Mellon University.

...................... ..

Suggestion:

After i Read Effective Java (by Joshua Bloch mailto: joshua.bloch@sun.com), i Find Some Questions:

1. In Item 7: Obey The General Contract athen overriding equals

"IT Turns Out That this Is A Fundamental Problem of

Equivalence Relations in Object-Oriented Languages. There is Simply No Way To

Extend an instantiable class and add an aspect while preserving the equals

Contract. "

I Think We CAN Modify Function Point.equals to do this, make it it returns True Only When Two Object Have The Same Class Type.

Public Class Point Extends Point2D Implements Java.io.Serializable {

// ...

Public Boolean Equals (Object Obj) {

IF (Obj == null) {

Return False;

}

IF (getClass (). Equals (obj.getclass ()) == false) {

Return False;

}

Point Pt = (POINT) Obj; return (x == pt.x) && (y == pt.y);

}

}

Public Class ColorPoint Extends Point {

Private color color;

Public ColorPoint (int X, int y, color color) {

Super (x, y);

THIS.COLOR = Color;

}

Public Boolean Equals (Object O) {

IF (Obj == null) {

Return False;

}

IF (getClass (). Equals (obj.getclass ()) == false) {

Return False;

}

ColorPoint CP = (ColorPoint) O;

Return super.equals (o) && cp.color == color;

}

}

There is no questionm..

I Suggest this sales be a general rule for overwrite function equals ().

2. ITEM 16: Use interfaces insteadof abstract classes.

I Think Sun Should Remove Interfaces from Java. And The Rule Should Be "Replace Interfaces with Abstract Classes".

Interfaces result a problem, that is version not compatitable. Once you release a java interface, others use it, you can not modfiy it any more. Cause if you add a funtion to that java interface, others code can not compile. When You change to abstract classes, everything is ok, you can add new functions later free.

For example, if Sun add a new function in java.lang.Runnable, many java multi-thread writen with Runnable interface can not compile. This also happen in java JDBC, Sun use interfaces such as Connection. When Sun release a new jdk version, for example, from jdk1.4.1 to jdk1.4.2, Sun add some new functions to Connection interface. And programmers who upgrade their jdk to jdk1.4.2 find they can not compile their code since the JDBC driver they use did not implement those new functions in Connection interface. This is not acceptable. Why new jdk can not comile code that compile ok in early version? No reason.Another example is LayoutManager, Sun need to add more function for this interface, they have to add A New Layoutmanager2 Interface.that IS Not a Good Way, But They Have No Choice.

In java swing module, there are a lot of interfaces for event. But Sun keep on add more functions in old interface in new jdk. This will cause old code compile error. They have to add a new abstract class named as XXXAdapter for each event Interface. And Programmer SHOULD USTETESE XXXADAPTER CLASTETEADOF EVENT Interface.in this Way, They Can Compile Old Code WITHEROR USING New JDK.THAT IS Not a Good Way.

I Think Sun Should Modify Java Class Object Like this:

Public class object {

// ... Old Code

PRIVATE HASHMAP M_INTERFACESMAP = New HashMap ();

Public void addinterface (Object O) {

m_interfacesmap.put (O.GetClass (), O);

}

Public Object GetInterface (Class C) {

Object result = m_interfacesmap.get (c);

IF (result! = null) {

Return Result;

}

Iterator iteratorinterinterfaceObj = m_interfacesmap.values ​​(). Iterator ();

While (iteratorinterfaceObj.hasnext ()) {

Object o = iteratorinterfaceObj.next ();

IF (C.Isinstance (O)) {RETURN O;

}

}

Return NULL;

}

Public Boolean SupportInterface (Class C) {

IF (m_interfacesmap.get (c)! = NULL) {

Return True;

}

Iterator iteratorinterinterfaceObj = m_interfacesmap.values ​​(). Iterator ();

While (iteratorinterfaceObj.hasnext ()) {

Object o = iteratorinterfaceObj.next ();

IF (C.isInstance (O)) {

Return True;

}

}

Return False;

}

}

And We can now remove interface from java now.

Jacklondon Chen

Joshua Bloch Replied Email About General Contract When Overriding Equals. AS for Interface Version Problem, He Said Few Words.

> Suggestion:

> After i read Effective Java (by Joshua Bloch Mailto: Joshua.bloch@sun.com), i Find Some Questions:

>

> 1. In Item 7: Obey The General Contract athen overriding equals

>

> "IT Turns Out That this Is A Fundamental Problem of

> Equivalence Relations In Object-Oriented Languages. There is simply no way

> Extend an instantiable class and add an assect while preserving the equals

> contract. "

>

> I Think We can modify function point.equals to do this, make it it returning. Only When Two Object Have the Same Class Type.

>

> Public Class Point Extends Point2d Implements Java.io.Serializable {

>

> // ...

>

> Public Boolean Equals (Object Obj) {

> IF (obj == null) {

> RETURN FALSE;

>}

> IF (getClass (). Equals (obj.getclass ()) == false) {

> RETURN FALSE;

>}

>

> Point Pt = (POINT) OBJ;

> RETURN (x == pt.x) && (y == pt.y);

>

>}

>

>}

>

> Public Class ColorPoint Extends Point {

> Private Color Color;>>>>>>

> Public ColorPoint (int x, int y, color color) {

> Super (x, y);

> This.color = color;

>}

>

> Public Boolean Equals (Object O) {

> IF (obj == null) {

> RETURN FALSE;

>}

> IF (getClass (). Equals (obj.getclass ()) == false) {

> RETURN FALSE;

>}

>

> ColorPoint CP = (ColorPoint) O;

> RETURN Super.Equals (O) && cp.color == Color;

>}

>}

>

> There is no problem about symmetry or transitivity.

> I suggest this sales be a general rule for overwrite function equals ()

>

>

TECHNICALLY SPEAKING You are Correct. A getclass-based Equals Method

ALLOWS you to add an "aspect" (a field that affects equals commit

To a subclass welch violating the letter of the equals contract, but

IT Has Other, More Serious Problems. in Particular, You Sacrium

Substitutability (The Liskov Substitution Principle) and with with it, the

Principle of Least Astonishment. This Matter is Somewhat

Controversial. The Bulk of Java Experts (Including Doug LEA) AGREE with

My Position On this, But a few people (NOTABLY Angelika Langer)

Disagree. I Was Planning ON Writing Up The Controversy, But Never

Finished it .. here's a Rough, Incomplete Draft:

Many People Have MAILED Me To Say That * Is * Possible to Extend An

Instantiable Class and Add An Aspect While PreserVing The Equals Contract,

Contrary to my claim in item 7. Other books have recommended these

"GetClass-based Equals Methods," and My Book (item 7) DIDN '' d d

Im. i

Considered Discussing this Topic in Item 7, But Decided Against It BecauseItem 7 Was Already So ​​Long and Complex. on Balance, this May Have Been A

Mistake. Had I Known How Controversial this Topic Was, And How Well-KNow

The getClass Approach, I Would Have Discussed It. I Plan on Posting AN

Essay

On this Topic On The Books Web Site, But I Haven't Had Time To Finish

Writing

IT. Here it is in rough form:

THIS TECHNIQUE ("getclass-based equals methods") Does Satisfy the equals

Contract, But at Great Cost. The disadvantage of the getclass approach

Is That It Violates The "Lisk Substitution Principle," Which States

(Roughly Speaking) That a Method Expecting a Superclass Instance Must

Behave Properly When Presented with a subclass instance. if a subclass

Adds a few new methods, or trivially modifies behavior (E.g., by

Emitting a TRACE UPON Each Method Invocation, Programmers Will B

Surprised when subclass and superclass instances don't interact

Properly. Objects That "OUGHT TO BE Equal" Won't Be, Causeing Programs

To fail or behave Erratically. The problem is exacerbated by the fater

That Java's Collectes Are Based on the equals method.

Here's A Simple Example That Doesn't Involve Collectes. Suppose you

Have a complex number class with a getclass-based equals method:

Public class complex {

Private Double Re;

Private Double Im;

Public Static Final Complex ORIGIN = New Complex (0.0, 0.0);

Public Complex (Double Re, Double Im) {

THIS.RE = RE;

THIS.IM = IM;

}

Final Public Boolean Equals (Object O) {

IF (o == null || getClass ()! = O.getClass ()) // QuestionsAble

Return False;

Complex C = (Complex) O;

Return C.re == Re && C.im == Im;}

Final public double norm () {return math.sqrt (re * re iM * im *});}

// The Standard Definition of Signum on A Complex Number

Final public complex signum () {

IF (this.equals (Origin))

Return Origin;

Double Norm = Norm ();

Return New Complex (RE / NORM, IM / NORM);

}

...

}

All of this May Seem Fine, But Look What Happens if you Extend Complex

In Some Innocuous Way, Create An Instance of The Subclass Whose Ree

Im Values ​​Are Both 0.0, And Invoke The Signum Method. The Initial

Equals Test Returns False, And Signum Divides by Zero (TWICE) AND

SILENTLY RETURN The WRONG ANSWER, A Complex Number Whose REAL AND

Imaginary Parts Are Both Nan! (The Correct Answer IS Origin.) This Not

An isolated example. it takes more care to write a non-final class with

A getclass-based equals method.

Equals Methods Based On GetClass Provide Very Different Semantics from

Those Based on InstanceOf. Many Java Programmers Expect The Latter

Semantics, In Part Because The Great Majority of classes in the java

Platform Libraries Use InstanceOf-based Equals Methods. if Interclass

Comparisons All Return False (As the Do with getClass-based Equals

Methods, Subclasses May Behave Erratically and Programmers May Be at a

Loss to understand why. Note Also That Mixing The Two Approaches in A

Single Hierarchy Products Meaningness Results.

A minor disadvantage of the getclass approach is that it Requires a

Separate Null-Test to Achieve The Correct Behavior. The Null-Test IS

Performed Automaticly by The InstanceOf Operator, AS Described on Page

32.

I shop reitedrate what one can argue for Both approaches. With the

InstanceOf Approach, It's Easy to Write "Trivial Subclasses" Andimpossible To Add An Aspect (A Field Used In Equals Comparisons). with

THE GETCLASS Approach It's Possible To Add An Aspect (Assuming You're

Willing to have the subclass instances not interact with the superclass

Instances) But it is impossible to create a subclass what it is usable

Anywhere the superclass is usable, Even A "Trivial Subclass." While the

InstanceOf Approach Predominates, Some Respected Authors Do Consider THE

GetClass Approach to Be Acceptable.

One Last Thing Worth Menting Is That Controversy Is Far Less

Important Than IT Might Appear. The Vast Majority of Classes Should Not

Override Object.Equals at all. Only Value Classes (Or Other Classes

With value semantics) Should Do So. Furthermore, Most Value Classes

Should Be Immutable, Hence Final. If A Class Is Final, IT Doesn't

Matter Which of The Two Kinds of Equals Methods It Has.

From a theoretical personpect, it is offen supect to add an assect in

A subclass, as it offen violates the "IS-a" test. for example, Some

Books Have A 3-Dimensional Point (Point3) Subclass A 2-Dimensional Point

(Point2). However, it is * not * The case tria 3-Dimensional Point Is A

2-Dimensional Point! A 3-Dimensional Point May Be * Viewed * as a

2-Dimensional Point in Any Of Three Ways (Projection ONTO X-Y Plane,

Projection Onto Y-Z Plane, Projection ONTO X-Z Plane). Note That My

SuggeSted ​​Solution (p. 31) Meshes Well with this Situation: One Can Add

Three Separate 2-D-Point-Returning View Methods to the 3-D Point Class.

Prof. Mads Torgersen Summed IT Up this Way:

"IT's Amazing How Many Interesting Problems Of Object-Oriented

Abstract you canfix by doing away with object-orient Abstract. It's like hold your YOUR

Breath to get rid of hiccups: if you do it long enough its Guaranteed to

Work. "

> 2. ITEM 16: Use interfaces insteadof abstract classes.

>

> I Think Sun SHOULD Remove Interfaces from Java

>

I Assume you know That this Would Be Impossible Even IF IT WERE

Advisable. It Would Represent A Gross Incompatibility, Breaking

Millions of Existing Programs. That Said, I Think IT Would Be a Very

Bad IDEA. Interfaces Are The Heart and Soul of The Java Programming

Language.

> And the rule shop be "Replace Interfaces with Abstract Classes".

>

>

Nope. You Correctly Point Out That Is Easier To Evolve An Abstract

Class Than An Interface. in Fact Item 16 Says this and review it in

ITS Closing Paragraph. WHERE EVOLUTION IS OF Paramount Importance,

Abstract Classes May Be Preference To Interfaces. Generally Speaking,

However, The IncreaSed Flexibility of Implementation Afforded by

Interfaces make the reason. this Topic is Less Controversial Than

The Previous ONE. (To the Best of My Knowledge, You're The First Person

Ever to take itssue with item 16.)

Happy new year,

Josh

I Found That Sests About "The General Contract When Overriding Equals" Still Had Some Bugs in It. SO i Changed The Code and Resend A Mail:

Dear MR Bloch,

It's my great honor to receive your email. Thank you very much.

AS for Item 7: Obey The General Contract When Overriding Equals,

I Find a Good Way to Solve this Question. That's to check class which define equals function.

Public class point {

Public Boolean Equals (Object Other) {

IF (Checkequalstool.hassameDeclaringequalsclass (this, other) {Point OtherPoint = (Point) other;

Return x == OtherPoint.x && y == Otherpoint.y;

}

Else {

Return False;

}

}

}

Public Class ColorPoint

Extends point {

Private color color;

Public colorPoint () {

Super (0, 0);

this.color = color.black;

}

Public ColorPoint (int X, int y, color color) {

Super (x, y);

THIS.COLOR = Color;

}

Public Boolean Equals (Object Other) {

IF (Checkequalstool.hassameDeclaringequalsclass (this, other) {

ColorPoint OtherColorPoint = (colorpoint) other;

Return Super.equals (Other) && Color == OtherColorPoint.color;

}

Else {

Return False;

}

}

}

Public class checkequalstool {

Public Static Boolean HassameDeclaringequalsclass (Object Obj, Object Other) {

IF (Obj == Null || Other == NULL) {

Return False;

}

Class thisDeclaringequalsclassclass = getDeclaringequalsclass

Obj);

Class OtherDeclaringequalsclass = getDeclaringequalsclass (

Other);

Return thisDeclaringequalsclass.equals (OtherDeclaringequalsclass);

}

Private static class getDeclaringequalsclass (object obj) {

Class declaringequalsclass = null;

Try {

Method method = Obj.getClass (). GetMethod ("Equals",

NEW class [] {Object.class});

Declaringequalsclass = method.getdeclaringclass ();

}

Catch (Exception E) {

Declangequalsclass = null;

}

Return DeclanGequalsclass;

}

}

AS for Item 16: Use interfaces insteadof abstract classes:

I Just Finish Leading a Java Application Project. No One is allowed to create Java Interface. We get Very Good Version Compatibility.

I don't why sun don't About Java Source Version Compament.

As a BASIC general rule, programmer update software develope tools, all old code is supposed to be compiled OK with new version tools.Anyway, we can not do this when we use java interface. We feel good without java interface.

If You Write a Java Interface and Others Use it, you cannot add code to it. This may cause Others Code Compile Error.

I Have CHECK There So Many Java AWT / SWING Event Use Java Interface for Event Listener and Abstract Class for Event Interface Adapter,

For example:

Public interface keylistener extends EventListener {

Public void keytyped (KeyEvent E);

Public void keypressed (KeyEvent E);

Public void keyreleased (KeyEvent E);

}

Public Abstract Class KeyAdapter Implements Keylistener {

Public void keytyped (keyevent e) {}

Public void keypressed (KeyEvent E) {}

Public void keyreleased (KeyEvent E) {}

}

I Think The Is No Reason for Existence of Keylistener, Both JDK and Programmer Use KeyAdapter is Good.

Sorry to bother you.

Jacklondon Chen

转载请注明原文地址:https://www.9cbs.com/read-128360.html

New Post(0)