Montag, 6. Juni 2011
Autoboxing in Java
Folgendes Beispiel zeigt ein Problem beim Autoboxing in Java. Der Autor des Code-Fragments will int
-Werte in der LinkedList
speichern. Das funktioniert beim Speichern in Zeile 16 auch super, weil der int
-Wert recNo
automatisch in ein Integer
-Objekt gepackt wird.
LinkedList<Integer> lockedRecords = new LinkedList<Integer>(); public long lock(int recNo) throws RemoteException, RecordNotFoundException { long lockCookie = 0; if(existsRec(recNo)){ synchronized(records.get(recNo)){ while(lockedRecords.contains(recNo)){ try { records.get(recNo).wait(); } catch (InterruptedException ex) { System.err.println("Lock Interrupted!"); } } if(existsRec(recNo)){ lockedRecords.add(recNo); boolean lock_getted = true; lockCookie = lockedRecords.size() -1; return lockCookie; } } }else{ throw new RecordNotFoundException(); } return lockCookie; } public void unlock(int recNo, long lockCookie) throws RemoteException, RecordNotFoundException, SecurityException { if(recNo > 0 && recNo < records.size()){ if(lockCookie >= 0 && lockCookie < lockedRecords.size() && lockedRecords.contains((int)lockCookie)){ synchronized(records.get(recNo)){ lockedRecords.remove(recNo); records.get(recNo).notifyAll(); } }else{ throw new SecurityException(); } }else{ throw new RecordNotFoundException(); } }
unlock()
stürzt (praktisch) immer in Zeile 34 ab! Und zwar mit einer IndexOutOfBoundsException
.
Warum?
Die Klasse LinkedList
(sowie viele andere Klassen des Java Collection Frameworks) besitzt zwei remove()
-Methoden:
E remove(int index)
, welche das Element mit dem Index index entfernt und eineIndexOutOfBoundsException
wirft, wenn der Index nicht existiert.- boolean remove(Object o), welche das entsprechende Objekt entfernt, falls es existiert (und in diesem Fall
true
liefert).
int
-Parameter wird nicht automatisch in ein Integer
-Objekt verpackt, da zuerst die zu int
passende Methode verwendet wird! E remove(int index)
wirft aber eine IndexOutOfBoundsException
, wenn der int recNo
kein gültiger Index ist. Das wäre eher zufällig passend.
Autoboxing ist also im Allgemeinen sehr praktisch, kann aber zu unerwarteten Problemen führen.
Übrigens ist eine Lösung mit Verwendung von Integer
nicht zielführend, da beim Autoboxing nur bei kleinen Werten tatsächlich dasselbe Objekt verwendet wird:
Integer i1 = 23; Integer i2 = 23; Integer i3 = 2132321423; Integer i4 = 2132321423; System.out.println(i1 == i2); System.out.println(i1.equals(i2)); System.out.println(i3 == i4); System.out.println(i3.equals(i4));liefert:
true true false true
Abonnieren Posts [Atom]
Kommentar veröffentlichen