/ Forside / Teknologi / Udvikling / Java / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Java
#NavnPoint
molokyle 3688
Klaudi 855
strarup 740
Forvirret 660
gøgeungen 500
Teil 373
Stouenberg 360
vnc 360
pmbruun 341
10  mccracken 320
Inner class med virtuel overskrevet metode~
Fra : Lasse Reichstein Nie~


Dato : 13-12-03 02:11


Jeg løb ind i denne situation i dag: En inner class som virtuelt
overskriver en metode fra sin superklasse, og hvis superklasses
konstruktor kalder denne metode.

Problemet er at indtil superklassens konstruktor bliver færdig har
inner-class'en ikke en reference til sin ydre klasse, så hvis metoden
henviser til felter i den ydre klasse, så giver det en Null Pointer
Exception.

Et eksempel på kode:
---
class Outer {
public static void main(String args[]) {
Outer o = new Outer();
Inner i = o.new Inner();
}
class Inner extends Super {
Inner () {
method();
}
void method() {
System.out.println(Outer.this);
}
}
}
abstract class Super {
Super() {
method();
}
abstract void method();
}
---

Spørgsmålet er så: Er det korrekt opførsel? Jeg kunne ikke finde et
sted i JLS2 der svarede på det. Hvis nogen kan pege på et sted (eller
flere steder) der viser at det er korrekt opførsel, så vil jeg være
taknemmelig.
<URL:http://java.sun.com/docs/books/jls/second_edition/html/jTOC.doc.html>

(Jeg har løst problemet ved at omskrive programmet, men jeg vil gerne
forstå det bedre).

/L
--
Lasse Reichstein Nielsen - lrn@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'

 
 
Michael Banzon (13-12-2003)
Kommentar
Fra : Michael Banzon


Dato : 13-12-03 02:38

"Lasse Reichstein Nielsen" <lrn@hotpop.com> skrev...
> Spørgsmålet er så: Er det korrekt opførsel? Jeg kunne ikke finde et
> sted i JLS2 der svarede på det. Hvis nogen kan pege på et sted (eller
> flere steder) der viser at det er korrekt opførsel, så vil jeg være
> taknemmelig.
> <URL:http://java.sun.com/docs/books/jls/second_edition/html/jTOC.doc.html>
>
> (Jeg har løst problemet ved at omskrive programmet, men jeg vil gerne
> forstå det bedre).

Jeg har ike forsøgt med din kode, men noget tilsvarende virker ellers
fint nok her hos mig... ???


--
Michael Banzon
http://michael.banzon.dk/
http://southbound.dk/blog/



Lasse Reichstein Nie~ (13-12-2003)
Kommentar
Fra : Lasse Reichstein Nie~


Dato : 13-12-03 13:47

Lasse Reichstein Nielsen <lrn@hotpop.com> writes:

> Spørgsmålet er så: Er det korrekt opførsel? Jeg kunne ikke finde et
> sted i JLS2 der svarede på det.

Jeg fandt nu noget der måske giver svaret (i JLS2, afsnit 8.8.5.1)
---
Finally, if the constructor invocation statement is a superclass
constructor invocation and the constructor invocation statement
completes normally, then all instance variable initializers of C and
all instance initializers of C are executed.
---
Det vil sige at objektet ikke er initialiseret endnu da superklassens
konstruktor kalder den overskrevne metode. Det inkluderer åbenbart også
den skjulte reference til den ydre klasse.


Så blev jeg så meget klogere. :)
/L
--
Lasse Reichstein Nielsen - lrn@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'

Jonas Kongslund (13-12-2003)
Kommentar
Fra : Jonas Kongslund


Dato : 13-12-03 15:25

Lasse Reichstein Nielsen wrote:
> Det vil sige at objektet ikke er initialiseret endnu da superklassens
> konstruktor kalder den overskrevne metode. Det inkluderer åbenbart også
> den skjulte reference til den ydre klasse.

Ja. Oversættelse af Outer.java vil bl.a. producere følgende bytecode

Method Outer. Inner(Outer)
0 aload_0
1 invokespecial #1 <Method Super()>
4 aload_0
5 aload_1
6 putfield #2 <Field Outer this$0>
9 aload_0
10 invokevirtual #3 <Method void method()>
13 return

Linje 0-1 kalder superklassens konstrutør.
Linje 4-6 sætter Inner's såkaldte enclosing reference
Linje 9-13 kalder den resterende del af konstruktøren

Ganske som beskrevet i §12.5 (Creation of New Class Instances).

Mon ikke opførelsen vil have været defineret anderledes hvis indre klasser
var med fra starten af? Med andre ord: er der noget begrebsmæssigt til
hinder for at en eventuel enclosing reference sættes inden superklassens
konstruktør kaldes hvis det ikke lige er pga. bagudkompatibilitet af hensyn
til de mange JVM-implementationer som efterhånden er blevet lavet?

--
Jonas Kongslund

Lasse Reichstein Nie~ (13-12-2003)
Kommentar
Fra : Lasse Reichstein Nie~


Dato : 13-12-03 16:46

Jonas Kongslund <dont@mail.me.at.all> writes:

> Ganske som beskrevet i §12.5 (Creation of New Class Instances).

Takker, lige sådan noget jeg skulle bruge (og at forstå at referencen
til den ydre klasse er en instansvariabel med en initialisator).

> Mon ikke opførelsen vil have været defineret anderledes hvis indre klasser
> var med fra starten af? Med andre ord: er der noget begrebsmæssigt til
> hinder for at en eventuel enclosing reference sættes inden superklassens
> konstruktør kaldes hvis det ikke lige er pga. bagudkompatibilitet af hensyn
> til de mange JVM-implementationer som efterhånden er blevet lavet?

Godt gæt, jeg håber det ville vare anderledes. Jeg synes ikke
nødvendigvis at det er smart at en konstruktor kan kalde metoder på et
objekt der ikke er ordentligt initialiseret.

/L
--
Lasse Reichstein Nielsen - lrn@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'

Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408918
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste