<?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</title>
	<atom:link href="http://www.ingokallenbach.de/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>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Maven-Update unter Mac OS X</title>
		<link>http://www.ingokallenbach.de/2009/11/01/maven-update-unter-mac-os-x/</link>
		<comments>http://www.ingokallenbach.de/2009/11/01/maven-update-unter-mac-os-x/#comments</comments>
		<pubDate>Sun, 01 Nov 2009 12:49:46 +0000</pubDate>
		<dc:creator>ingo</dc:creator>
				<category><![CDATA[Allgemeines]]></category>

		<guid isPermaLink="false">http://www.ingokallenbach.de/?p=110</guid>
		<description><![CDATA[Auf meinem Snow Leopard System habe ich ein Maven bereits vorinstalliert. Es kann allerdings gut sein, dass Maven mit XCode installiert wurde. Das kann ich gerade nicht genauer sagen.
Jedenfalls habe ich Maven in Version 2.0.9 auf meinem System vorgefunden. Aktuell ist aber Maven in Version 2.2.1. Um nun Maven auf den aktuellen Stand zu bringen, [...]]]></description>
			<content:encoded><![CDATA[<p>Auf meinem Snow Leopard System habe ich ein <a href="http://maven.apache.org">Maven</a> bereits vorinstalliert. Es kann allerdings gut sein, dass Maven mit XCode installiert wurde. Das kann ich gerade nicht genauer sagen.</p>
<p>Jedenfalls habe ich Maven in Version 2.0.9 auf meinem System vorgefunden. Aktuell ist aber Maven in Version 2.2.1. Um nun Maven auf den aktuellen Stand zu bringen, ist erstmal die aktuelle Version <a href="http://maven.apache.org/download.html">runterzuladen</a>. Das runtergeladene Archiv wird entpackt.</p>
<p>Jetzt ist ein wenig Tipperei auf der Konsole angesagt. Also das <em>Terminal</em> gestartet.</p>
<p>Der Befehl <code>which mvn</code> zeigt uns, dass Maven über <code>/usr/bin/mvn</code> aufgerufen wird. Schaut man noch genauer hin und verfolgt die ganzen symbolischen Links, stößt man im Endeffekt auf <code>/usr/share/java/apache-maven-2.0.9</code>. Damit ist ein Update sehr einfach!</p>
<ol>
<li>In das Verzeichnis <code>/usr/share/java</code> wechseln (<code>cd /usr/share/java</code>).</li>
<li>Die entpackte neue Maven Version dorthin kopieren (<code>sudo cp -r /path/to/apache-maven-2.2.1 .</code>).</li>
<li>Ein Verzeichnis höher wechseln (<code>cd ..</code>).</li>
<li>Den alten Link entfernen (<code>sudo rm maven</code>).</li>
<li>Auf das neue Maven verlinken (<code>sudo ln -s java/apache-maven-2.2.1 maven</code>).</li>
</ol>
<p>Nach diesen Schritten sollte sich Maven mit der Version 2.2.1 melden.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ingokallenbach.de/2009/11/01/maven-update-unter-mac-os-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Daten unter Mac OS X verschlüsseln</title>
		<link>http://www.ingokallenbach.de/2009/08/10/daten-unter-mac-os-x-verschlusseln/</link>
		<comments>http://www.ingokallenbach.de/2009/08/10/daten-unter-mac-os-x-verschlusseln/#comments</comments>
		<pubDate>Mon, 10 Aug 2009 18:12:07 +0000</pubDate>
		<dc:creator>ingo</dc:creator>
				<category><![CDATA[macosx]]></category>
		<category><![CDATA[verschlüsselung]]></category>

		<guid isPermaLink="false">http://www.ingokallenbach.de/?p=77</guid>
		<description><![CDATA[Möchte man unter Mac OS X Daten verschlüsseln, so ist das bereits mit Bordmitteln erreichbar.
FileVault
Da wäre FileVault, das das kompletten Homeverzeichnis verschlüsselt. FileVault lässt sich unter den Systemeinstellungen im Bereich &#8220;Sicherheit&#8221; aktiveren.
Da FileVault das gesamte Homeverzeichnis verschlüsselt, kann das Auswirkungen auf die Performance des Rechners haben. So werden z.B. alle Downloads und Browser-Cache-Dateien ebenfalls verschlüsselt, [...]]]></description>
			<content:encoded><![CDATA[<p>Möchte man unter Mac OS X Daten verschlüsseln, so ist das bereits mit Bordmitteln erreichbar.</p>
<h3>FileVault</h3>
<p>Da wäre FileVault, das das kompletten Homeverzeichnis verschlüsselt. FileVault lässt sich unter den Systemeinstellungen im Bereich &#8220;Sicherheit&#8221; aktiveren.</p>
<p>Da FileVault das gesamte Homeverzeichnis verschlüsselt, kann das Auswirkungen auf die Performance des Rechners haben. So werden z.B. alle Downloads und Browser-Cache-Dateien ebenfalls verschlüsselt, da sie im Homeverzeichnis landen.</p>
<h3>Verschlüsseltes Disk Image</h3>
<p>Verschlüsselte Disk Images sind das 2. Bordmittel von Mac OS X, um Daten verschlüsselt abzulegen. Solch ein Disk Image wird über das Festplatten-Dienstprogramm (Disk Utility) erstellt.</p>
<p>Beim Erstellen eines neuen Disk Images muss man angeben, wo das Image abgelegt werden soll. Es folgen die Einstellungen zur (Start-)Größe des Images, zur Verschlüsselung und zum Format des Images (es sollte mitwachsen).</p>
<div id="attachment_79" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.ingokallenbach.de/wp-content/uploads/2009/08/newEncryptedDiskImage.png" rel="lightbox[77]"><img class="size-medium wp-image-79" title="newEncryptedDiskImage" src="http://www.ingokallenbach.de/wp-content/uploads/2009/08/newEncryptedDiskImage-300x231.png" alt="Erstellung eines neuen, verschlüsselten Disk Images." width="300" height="231" /></a><p class="wp-caption-text">Erstellung eines neuen, verschlüsselten Disk Images.</p></div>
<p>Nachdem alle Parameter zur Erstellung des verschlüsselten Disk Images angegeben sind wird das Image erstellt. Nun muss ein Passwort festgelegt werden.</p>
<div id="attachment_80" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.ingokallenbach.de/wp-content/uploads/2009/08/password4encryptedDiskImage.png" rel="lightbox[77]"><img class="size-medium wp-image-80" title="password4encryptedDiskImage" src="http://www.ingokallenbach.de/wp-content/uploads/2009/08/password4encryptedDiskImage-300x213.png" alt="Passwort für das verschlüsselte Disk Image" width="300" height="213" /></a><p class="wp-caption-text">Passwort für das verschlüsselte Disk Image.</p></div>
<p>Danach ist das verschlüsselte Disk Image angelegt und kann per Doppelklick gemountet werden. Ist das Image gemountet kann es normal benutzt werden.</p>
<p>Das verschlüsselte Disk Image wächst zwar nun schön mit, wird aber nicht mehr kleiner. Um die Größe des Images einzudampfen muss im Terminal folgender Befehl verwendet werden (das Image darf nicht gemountet sein!):</p>
<p><code>hdiutil compact encryptedDiskImage.sparcebundle</code></p>
<p>Man wird nach dem Passwort für das Disk Image gefragt und anschließend wird die Größe des Images verringert. Es folgt noch eine Zusammenfassung, wie viel Platz eingespart werden konnte.</p>
<div id="attachment_106" class="wp-caption aligncenter" style="width: 557px"><a href="http://www.ingokallenbach.de/wp-content/uploads/2009/08/hdiutilCompact.png" rel="lightbox[77]"><img class="size-full wp-image-106" title="hdiutilCompact" src="http://www.ingokallenbach.de/wp-content/uploads/2009/08/hdiutilCompact.png" alt="hdiutil compact" width="547" height="135" /></a><p class="wp-caption-text">hdiutil compact</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.ingokallenbach.de/2009/08/10/daten-unter-mac-os-x-verschlusseln/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Veränderung kapseln</title>
		<link>http://www.ingokallenbach.de/2009/08/10/veranderung-kapseln/</link>
		<comments>http://www.ingokallenbach.de/2009/08/10/veranderung-kapseln/#comments</comments>
		<pubDate>Mon, 10 Aug 2009 16:31:41 +0000</pubDate>
		<dc:creator>ingo</dc:creator>
				<category><![CDATA[best-practices]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[coding-best-practices]]></category>
		<category><![CDATA[soft-dev]]></category>

		<guid isPermaLink="false">http://www.ingokallenbach.de/?p=86</guid>
		<description><![CDATA[Eine Konstante in der Softwareentwicklung, egal wo, was oder in welcher Programmiersprache man entwickelt: Veränderung. Es ist eigentlich egal, wie gut man eine Anwendung entworfen hat. Im Lauf der Zeit wird sie wachsen und sich wandeln müssen.
Für die Wartung und Wiederverwendung von Elementen/Klassen einer Anwendung ist es besser, wenn nicht versucht wird, alles über Vererbung [...]]]></description>
			<content:encoded><![CDATA[<p>Eine Konstante in der Softwareentwicklung, egal wo, was oder in welcher Programmiersprache man entwickelt: <em>Veränderung</em>. Es ist eigentlich egal, wie gut man eine Anwendung entworfen hat. Im Lauf der Zeit wird sie wachsen und sich wandeln müssen.</p>
<p>Für die Wartung und Wiederverwendung von Elementen/Klassen einer Anwendung ist es besser, wenn nicht versucht wird, alles über Vererbung zu lösen. Wird stur vererbt, kann es schnell bei einer lokalen Änderung zu weitreichenden Seiteneffekten kommen. Dazu bietet sich das einfach Beispiel aus dem Buch &#8220;<em>Entwurfsmuster von Kopf bis Fuß</em>&#8221; an <img src='http://www.ingokallenbach.de/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<blockquote><p>
In einer Entensimulation gibt es die Superklasse Ente, die die Methoden <code>quacken</code> und <code>schwimmen</code> für alle Sub-Enten implementiert. Eine abtrakte Methode <code>anzeigen</code> wird von den Sub-Enten implementiert, um sich selbt darzustellen.</p>
<p>Nun sollen die Enten fliegen können.</p>
<p>Eine Möglichkeit per Vererbung packt die Methode <code>fliegen</code> direkt in die Superklasse Ente. Nur jetzt können z.B. auch Enten fliegen, die es gar nicht sollten, wie eine Gummiente. Wenn nun alle Enten die Methode <code>fliegen</code> überschreiben und praktisch leer implementieren, dann wäre das Problem gelöst, aber bei jeder neuen Ente muss man beachten, ob sie fliegen kann oder nicht.</p>
<p>Eine weitere Möglichkeit wäre die Verwendung eines <em>FlugFähig</em>-Interfaces, das nur von den Enten implementiert wird, die auch tatsächlich fliegen können. Allerdings wird dann Code verdoppelt, da alle fugfähigen Enten das Interface implementieren müssen. Ein Wartungsalptraum <img src='http://www.ingokallenbach.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .
</p></blockquote>
<p>Da also die Vererbung nicht der Weisheit letzer Schluss ist, kommt man zu folgendem Entwurfsprinzip:</p>
<blockquote><p><strong>Identifizieren der Aspekte, die sich ändern können und sie von denen trennen, die konstant bleiben.</strong></p></blockquote>
<p>In obigem Entenbeispiel wird die <code>fliegen</code> Methode in ein Interface herausgezogen und verschiedene Flugverhalten implementiert (z.B. &#8220;normales&#8221; fliegen und &#8220;nicht&#8221; fliegen). Jeder Ente wird nun eins der Flugverhalten-Implementierungen übergeben, das zu ihr passt.</p>
<p>Die unterschiedlichen Flugverhalten sind nun nur noch 1x implementiert und werden den Enten &#8220;aufgesteckt&#8221;. Das fördert Code-Wiederverwendung und die Änderung an einem Flugverhalten stört keine Enten, die ein anderes Flugverhalten haben.</p>
<p>Wie das konkret im Quellcode aussieht, gibts im nächsten Teil über <em>Programmieren auf eine Schnittstelle</em>.</p>
<h4>Literatur</h4>
<ul>
<li>FREEMAN, E und FREEMAN, E: <em>Entwurfsmuster von Kopf bis Fuß.</em> O&#8217;Reilly, 2006.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.ingokallenbach.de/2009/08/10/veranderung-kapseln/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wordpress Update</title>
		<link>http://www.ingokallenbach.de/2009/07/11/wordpress-update/</link>
		<comments>http://www.ingokallenbach.de/2009/07/11/wordpress-update/#comments</comments>
		<pubDate>Sat, 11 Jul 2009 09:13:13 +0000</pubDate>
		<dc:creator>ingo</dc:creator>
				<category><![CDATA[Allgemeines]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.ingokallenbach.de/2009/07/11/wordpress-update/</guid>
		<description><![CDATA[Eben Wordpress auf aktuellen Stand gebracht.
Jetzt muss ich endlich mal anfangen, mehr zu bloggen  .
]]></description>
			<content:encoded><![CDATA[<p>Eben Wordpress auf aktuellen Stand gebracht.</p>
<p>Jetzt muss ich endlich mal anfangen, mehr zu bloggen <img src='http://www.ingokallenbach.de/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ingokallenbach.de/2009/07/11/wordpress-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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 können per Reflection immer noch zusätliche Instanzen der Singleton-Klasse erzeugt werden.
  

 [...]]]></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;">
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;">
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>
]]></content:encoded>
			<wfw:commentRss>http://www.ingokallenbach.de/2008/08/17/singleton-in-java/feed/</wfw:commentRss>
		<slash:comments>0</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 darauf zu werfen!
Theorie
Wann sollte equals() überschrieben werden?
equals() muss definitiv nicht für jede Klasse überschrieben werden! Vom [...]]]></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;">
(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;">
(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;">
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>
]]></content:encoded>
			<wfw:commentRss>http://www.ingokallenbach.de/2008/07/24/equals-in-java/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Mehrere Inspektoren auf einmal öffnen</title>
		<link>http://www.ingokallenbach.de/2008/02/24/mehrere-inspektoren-auf-einmal-offnen/</link>
		<comments>http://www.ingokallenbach.de/2008/02/24/mehrere-inspektoren-auf-einmal-offnen/#comments</comments>
		<pubDate>Sun, 24 Feb 2008 14:10:00 +0000</pubDate>
		<dc:creator>ingo</dc:creator>
				<category><![CDATA[macosx]]></category>

		<guid isPermaLink="false">http://www.ingokallenbach.de/2008/02/24/mehrere-inspektoren-auf-einmal-offnen/</guid>
		<description><![CDATA[
Es gibt bei Programmen, die die Inspektoren benutzen einen Weg, mehrere Inspektoren auf einmal zu öffnen.


Zuerst muss dafür bereits ein Inspektor offen sein. Anschließend klickt man, während die Option-Taste (bzw. die Alt-Taste) gedrückt ist auf einen anderen gewünschten Inspektor. Je nach Platz auf dem Desktop ist das sicherlich ganz nett  .
]]></description>
			<content:encoded><![CDATA[<p>
Es gibt bei Programmen, die die Inspektoren benutzen einen Weg, mehrere Inspektoren auf einmal zu öffnen.
</p>
<p>
Zuerst muss dafür bereits ein Inspektor offen sein. Anschließend klickt man, während die <code>Option</code>-Taste (bzw. die <code>Alt</code>-Taste) gedrückt ist auf einen anderen gewünschten Inspektor. Je nach Platz auf dem Desktop ist das sicherlich ganz nett <img src='http://www.ingokallenbach.de/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ingokallenbach.de/2008/02/24/mehrere-inspektoren-auf-einmal-offnen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Komplette Pfadanzeige im Finder</title>
		<link>http://www.ingokallenbach.de/2008/02/09/komplette-pfadanzeige-im-finder/</link>
		<comments>http://www.ingokallenbach.de/2008/02/09/komplette-pfadanzeige-im-finder/#comments</comments>
		<pubDate>Sat, 09 Feb 2008 21:53:00 +0000</pubDate>
		<dc:creator>ingo</dc:creator>
				<category><![CDATA[macosx]]></category>

		<guid isPermaLink="false">http://www.ingokallenbach.de/2008/02/09/komplette-pfadanzeige-im-finder/</guid>
		<description><![CDATA[
Mit folgendem Tipp, den ich bei James gefunden habe, zeigt der Finder in der Titelleiste nicht nur den aktuellen Ordnernamen sondern den kompletten Pfad an.


defaults write com.apple.finder _FXShowPosixPathInTitle -bool YES


Mit dem Parameter NO kann man das auch wieder rückgängig machen, aber wofür? 


Aktiviert wird die Anzeige des kompletten Pfads mit einem Neustart des Finders, z.B. [...]]]></description>
			<content:encoded><![CDATA[<p>
Mit <a href="http://www.mactricksandtips.com/2008/01/enabling-folder-path-in-finder.html">folgendem Tipp</a>, den ich bei <a href="http://www.mactricksandtips.com">James</a> gefunden habe, zeigt der <emph>Finder</emph> in der Titelleiste nicht nur den aktuellen Ordnernamen sondern den kompletten Pfad an.
</p>
<pre>
defaults write com.apple.finder _FXShowPosixPathInTitle -bool YES
</pre>
<p>
Mit dem Parameter <code>NO</code> kann man das auch wieder rückgängig machen, aber wofür? <img src='http://www.ingokallenbach.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />
</p>
<p>
Aktiviert wird die Anzeige des kompletten Pfads mit einem Neustart des <em>Finders</em>, z.B. durch kurzes Ausloggen oder Neustarten des Rechners. Ich bin mir nicht mehr ganz sicher, ob das Standardverhalten ist oder durch eines meiner installieren Programme kommt, aber ich kann auch den <em>Finder</em> mit <code>Alt+Rechtsklick</code> anwählen und dann einen Relaunch des <em>Finders</em> durchführen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ingokallenbach.de/2008/02/09/komplette-pfadanzeige-im-finder/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
