<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ingokallenbach.de &#187; java</title>
	<atom:link href="http://www.ingokallenbach.de/category/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ingokallenbach.de</link>
	<description>About Mac OS X Leopard, Java, software development and other stuff...</description>
	<lastBuildDate>Sun, 03 Jan 2010 15:21:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Singleton in Java</title>
		<link>http://www.ingokallenbach.de/2008/08/17/singleton-in-java/</link>
		<comments>http://www.ingokallenbach.de/2008/08/17/singleton-in-java/#comments</comments>
		<pubDate>Sun, 17 Aug 2008 11:53:24 +0000</pubDate>
		<dc:creator>ingo</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[singleton]]></category>

		<guid isPermaLink="false">http://www.ingokallenbach.de/?p=56</guid>
		<description><![CDATA[Der Artikel Singleton Pattern in Java beschreibt einige Implementierungen des Singletons in Java, bevor am Ende auf die bisher oft angetroffene und favorisierte Lösung eingangen wird. Aber auch diese favorisierte Lösung hat in bestimmten Situationen Nachteile: Bei entsprechend privilegiertem Zugriff &#8230; <a href="http://www.ingokallenbach.de/2008/08/17/singleton-in-java/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Der Artikel <a title="Singleton Pattern in Java" href="http://www.theserverside.de/singleton-pattern-in-java">Singleton Pattern in Java</a> beschreibt einige Implementierungen des Singletons in Java, bevor am Ende auf die bisher oft angetroffene und favorisierte Lösung eingangen wird.</p>
<p>Aber auch diese favorisierte Lösung hat in bestimmten Situationen Nachteile:</p>
<ul>
<li>
    Bei entsprechend privilegiertem Zugriff können per Reflection immer noch zusätliche Instanzen der Singleton-Klasse erzeugt werden.
  </li>
<li>
    Soll das Singleton <code>Serializable</code> sein, so müssen alle Felder als <code>transient</code> markiert werden und die Methode <code>readResolve()</code> muss implementiert werden:</p>
<pre class="brush: java; title: ;">
private Object readResolve()
  return INSTANCE; // Just return the single instance..
}
</pre>
</li>
</ul>
<p>Setzt man Java 1.5 (oder später) ein, kann man das Singleton Pattern über einen Enum realisieren! Hier bekommt man eine sehr kleine &quot;Klasse&quot;, die beide obigen Nachteile <strong>nicht</strong> hat!</p>
<pre class="brush: java; title: ;">
public enum Singleton {
  // Guaranteed to be the single instance
  INSTANCE;

  public void doSomething() {...}
}
</pre>
<p>Diese Art des Singletons ist laut Item 3 in Effective Java die beste Art das Singleton Pattern in Java zu implementieren.</p>
<h3>Literatur</h3>
<h4>Bücher</h4>
<ul>
<li>
    BLOCH, J.: <em><a href="http://java.sun.com/docs/books/effective">Effective Java</a></em>. Addison-Wesley, 2nd Edition, 2008.
  </li>
</ul>
<h4>Links</h4>
<ul>
<li>
    <em><a href="http://www.ibm.com/developerworks/java/library/j-dcl.html">Double-checked locking and the Singleton pattern</a></em>. Mai 2002.
  </li>
<li>
    <em><a href="http://www.theserverside.de/singleton-pattern-in-java">Singleton Pattern in Java</a></em>. August 2006.
  </li>
</ul>
<div class="shr-publisher-56"></div>]]></content:encoded>
			<wfw:commentRss>http://www.ingokallenbach.de/2008/08/17/singleton-in-java/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>equals() in Java</title>
		<link>http://www.ingokallenbach.de/2008/07/24/equals-in-java/</link>
		<comments>http://www.ingokallenbach.de/2008/07/24/equals-in-java/#comments</comments>
		<pubDate>Thu, 24 Jul 2008 21:25:30 +0000</pubDate>
		<dc:creator>ingo</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://www.ingokallenbach.de/?p=25</guid>
		<description><![CDATA[Die equals() Methode gehört in Java automatisch zur öffentlichen Schnittstelle einer jeden Klasse, da sie jede Klasse von Object automatisch erbt. Da die Collections in Java viel Gebrauch von der equals() Methode machen, lohnt es sich mal einen tieferen Blick &#8230; <a href="http://www.ingokallenbach.de/2008/07/24/equals-in-java/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Die <code>equals()</code> Methode gehört in Java automatisch zur öffentlichen Schnittstelle einer <b>jeden Klasse</b>, da sie jede Klasse von <code>Object</code> automatisch erbt.</p>
<p>Da die <code>Collections</code> in Java viel Gebrauch von der <code>equals()</code> Methode machen, lohnt es sich mal einen tieferen Blick darauf zu werfen!</p>
<h3>Theorie</h3>
<h4>Wann sollte <code>equals()</code> überschrieben werden?</h4>
<p><code>equals()</code> muss definitiv nicht für jede Klasse überschrieben werden! Vom Aufwand wäre es sogar am Einfachsten, sie gar nicht zu implementieren <img src='http://www.ingokallenbach.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> . Dann ist jede Instanz dieser Klasse nur zu sich selbst <i>equal</i>.</p>
<p>Grob gesagt kann man die <code>equals()</code> Methode bei Klassen weglassen, die &#8220;Dienste&#8221; anbieten und bei denen ihr Inhalt keine große Bedeutung hat. Ganz im Gegenteil bei Klassen, die bestimmte Werte repräsentieren. Diese Klassen sind auch Kandidaten für die <code>Collections</code> von Java und benötigen damit höchstwahrscheinlich eine eigens implementierte <code>equals()</code> Methode!</p>
<h4>Der <code>equals</code>-Vertrag</h4>
<p>Die folgenden Bedingungen kann man auch direkt der Dokumentation von <code>Object</code> entnehmen:</p>
<ul>
<li>
<b>reflexiv:</b> für <code>x != null</code> muss gelten, dass <code>x.equals(x) true</code> zurückgibt
</li>
<li>
<b>symmetrisch:</b> für <code>x, y != null</code> muss gelten, dass <code>x.equals(y)</code> nur <code>true</code> gibt, wenn auch <code>y.equals(x) true</code> gibt
</li>
<li>
<b>transitiv:</b> für <code>x, y, z != null</code> muss gelten, dass wenn <code>x.equals(y)</code> und y.equals(z) true ergibt, dann muss auch <code>x.equals(z) true</code> ergeben
</li>
<li>
<b>konsistent:</b> für <code>x, y != null</code> muss gelten, dass mehrmalige Aufrufe von <code>x.equals(y)</code> konsistent <code>true</code> oder <code>false</code> zurückgibt, sofern sich an den Objekten nichts ändert
</li>
<li>
<code>x.equals(null)</code> muss <code>false</code> zurückgeben (und keine <code>NullPointerException</code>!)
</li>
</ul>
<p>Sie beschreiben den Vertrag, den man als Programmierer dringenst einhalten sollte. Tut man das nicht, ist nicht zu 100% garantiert, dass sich z.B. die <code>Collections</code> Klasse so verhalten, wie sie sollen.</p>
<p>Die letzte Bedingung (<code>x.equals(null) == false</code>) lässt sich mit einem einfachen <code>o instanceof Type</code> prüfen, da <code>instanceof</code> schon direkt <code>false</code> liefert, wenn das Objekt <code>o null</code> ist!</p>
<p>Während Objekthierarchien durchaus mit <code>super.equals(Object other)</code> arbeiten können, dürfen direkte Subklassen von <code>Object</code> dies nicht tun! Da <code>Object.equals(Object other)</code> nur mittels <code>==</code> prüft, wird so gut wie immer <code>false</code> zurückgegeben, außer beide Objekte verweisen auf die gleiche Referenz. Das ist aber gerade dann, wenn man <code>equals()</code> überschreibt höchstwahrscheinlich nicht gewünscht.</p>
<p>Wird eine Unterklasse abgeleitet und dieser Klasse eine Membervariable hinzugefügt, dann lässt sich die Transitivität nicht mehr ohne weiteres herstellen! Die Symmetrie funktioniert noch, da die Member der Unterklasse beim Vergleich mit der Oberklasse ignoriert werden können. Aber bei der Transitivität müsste die Oberklasse wieder mit der Unterklasse verglichen werden und dann kommt man nicht mehr an die Member.</p>
<h4><code>instanceof</code> oder <code>getClass()</code>?</h4>
<p>Es gibt im Prinzip 2 Lager: die <code>instanceof</code>-Verfechter und die, die <code>getClass()</code> favorisieren.</p>
<p>Mit <code>getClass()</code> stellt man sicher, dass definitiv beide Objekte (<code>this</code> und <code>other</code>) zur Laufzeit vom gleichen Typ sind (<code>instanceof</code> liefert ja auch beim Vergleich auf Oberklassen <code>true</code>). Man kann sich also ganz sicher sein, dass der <code>equals</code>-Vertrag eingehalten wird.</p>
<p>Allerdings wird argumentiert, dass die <code>getClass()</code> Methode das Substitutionsprinzip verletzt. Z.B. ist es nicht mehr möglich, von einer Klasse abzuleiten und nur Methoden zu überschreiben. Diese neue Unterklasse wird niemals <i>equal</i> mit ihrer Oberklasse sein.</p>
<p>Mit <code>instanceof</code> umgeht man dieses Problem und kann wieder das Substitutionsprinzip anwenden. Allerdings muss man obige Schilderung bedenken, dass man zu den abgeleiteten Klassen keine Member hinzufügen darf!</p>
<p>Allgemein bieten sich folgende Lösungen an:</p>
<ul>
<li>
Abstrakte Oberklassen, die keine eigenen Member definieren. Da man in diesem Fall die Oberklasse nicht direkt erzeugen kann.
</li>
<li>
Finale Klassen, die man erst gar nicht ableiten kann eignen sich natürlich hervorragend und arbeiten super mit <code>instanceof</code> zusammen. Diese Lösung ist sogar wahrscheinlich für fast alle &#8220;Werte&#8221;-Klassen optimal oder wer nutzt komplex verschachtelte Hierarchien von &#8220;Werte&#8221;-Klassen? Findet man sich darin noch zurecht? <img src='http://www.ingokallenbach.de/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />
</li>
</ul>
<h3>Implementierungsinfos</h3>
<p>Ausgehend von der Theorie kann man mit folgenden &#8220;Punkten&#8221; die <code>equals()</code> Methode implementieren:</p>
<ol>
<li>
<code>==</code> nutzen, um anfangs die eigene Identität zu prüfen. Das ist hauptsächlich eine Performance-Optimierung, die sich bei großen Objekten besonders auswirkt.
</li>
<li>
Mit <code>instanceof</code> prüfen, ob das übergebene Objekt vom richtigen Typ ist (und damit wird ja auch gleich geprüft, ob das übergebene Objekt vielleicht <code>null</code> ist&#8230;).
</li>
<li>
Das übergebene Objekt auf den eigenen Typ casten.
</li>
<li>
Für jede signifikante Membervariable prüfen, ob sie bei beiden Objekten übereinstimmt.</p>
<ul>
<li>
Primitive Member werden mit <code>==</code> verglichen (außer <code>float</code> und <code>double</code>).
</li>
<li>
<code>float</code> mit <code>Float.equals()</code> und <code>double</code> mit <code>Double.equals()</code> vergleichen, da es z.B. <code>Float.NaN</code> gibt!
</li>
<li>
Referenztypen mit <code>equals()</code> vergleichen.
</li>
<li>
Wenn die Referenztypen <code>null</code> sein können, dann bietet sich folgendes Konstrukt an:</p>
<ul>
<li>
<pre class="brush: java; title: ;">
(field == null ?
    other.field == null :
        field.equals(other.field))
</pre>
</li>
</ul>
</li>
<li>
Und wenn dabei auch noch <code>field</code> und <code>other.field</code> identisch sein können, bietet sich das Konstrukt an:</p>
<ul>
<li>
<pre class="brush: java; title: ;">
(field == other.field ||
    (field != null &amp;&amp; field.equals(other.field)))
</pre>
</li>
</ul>
</li>
</ul>
</li>
<li>
Am Ende sollte nochmals geprüft werden, ob die implementierte <code>equals()</code> transitiv, symmetrisch und konsistent ist.
</li>
</ol>
<p>Um die Performance noch etwas zu optimieren, könnem speziell unveränderbare (immutable) Objekte ihren kanonische Form vergleichen satt über alle Member zu gehen. Außerdem sollten die Member, die sich zwischen 2 Objekte oft unterscheiden anfangs überprüft werden, damit sich <code>equals()</code> in dem Fall schnell beenden kann.</p>
<p><b>Ganz wichtig:</b> wann immer <code>equals()</code> überschrieben wird, muss auch <code>hashCode()</code> überschrieben werden!</p>
<h3>Implementierungsbeispiel</h3>
<pre class="brush: java; title: ;">
public final class Person {
  private final Address address;
  private String prename;
  private int age;
  // ... more members ...

  // ... methods ...

  @Override
  public boolean equals(Object other) {
    if(other == this) {
      return true;
    }
    if(!(other instanceof Person)) {
      return false;
    }

    Person p = (Person) other;
    return this.age == p.age &amp;&amp;
      this.prename.equals(p.prename) &amp;&amp;
      (this.address == null ?
          p.address == null :
              this.address.equals(p.address)) &amp;&amp;
      // ... other comparisons ...
  }

  // ... methods ...
}
</pre>
<h3>Literatur</h3>
<h4>Bücher</h4>
<ul>
<li>
BLOCH, J.: <em>Effective Java</em>. Addison-Wesley, 2nd Edition, 2008.
</li>
</ul>
<h4>Links</h4>
<ul>
<li>
<em><a href="http://www.artima.com/intv/bloch17.html">instanceof versus getClass in equals() Methods</a></em>. Interview mit Josh Bloch, Januar 2002.
</li>
<li>
KREFT, K und LANGER, A.: <em><a href="http://www.angelikalanger.com/Articles/JavaSpektrum/01.Equals-Part1/01.Equals1.html">Implementing the equals() Method &#8211; Part 1</a></em>. Januar 2002.
</li>
<li>
KREFT, K und LANGER, A.: <em><a href="http://www.angelikalanger.com/Articles/JavaSpektrum/02.Equals-Part2/02.Equals2.html">Implementing the equals() Method &#8211; Part 2</a></em>. März 2002.
</li>
<li>
GOETZ, B.: <em><a href="http://www.ibm.com/developerworks/java/library/j-jtp05273.html">Java theory and practice: Hashing it out</a></em>. Mai 2003.
</li>
</ul>
<div class="shr-publisher-25"></div>]]></content:encoded>
			<wfw:commentRss>http://www.ingokallenbach.de/2008/07/24/equals-in-java/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

