/ 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
Nødder
Fra : Soren Kuula


Dato : 01-02-04 13:35

OK, sådan en søndag er keedelig, men . . .

Hvad bliver der skrevet ud når man kører dette program ?
Prøv regne det ud før du kører det :)
Det har intet at gøre med at jeg bruger indre klasser, det er bare for
at holde det nede på 1 fil.

/**
* @author snk
*/
public class BindingTimeExperiment {
   static class General {
      void method(General a) {
         System.out.println("General");
      }
      void method(Special a) {
         System.out.println("Special");
      }
   }

   static class Special extends General {
   }

   public static void main (String[] args) {
      General a = new General();
      Special b = new Special();
      General c = b;
      
      a.method(a);
      a.method(b);
      a.method(c);
   }
}

Hmmmm.. havde helt glemt at Java bandt metodekaldene så tidligt.

Og det her .. ?

/**
* @author snk
*/
public class InitializationExperiment {
   static class Super {
      Super() {
         init();
      }
      
      void init() {
System.out.println("Nice air up here");
      }
   }
   
   static class Sub extends Super {
      String stinker = "Some things just smell";
      
      void init() {
         System.out.println(stinker);
      }
   }
   
   public static void main (String[] args) {
      new Sub();
   }
}

*Ouch !*

MVH
Søren
--
Fjern de 4 bogstaver i min mailadresse som er indsat for at hindre s...
Remove the 4 letter word meaning "junk mail" in my mail address.


 
 
Ulrik Magnusson (01-02-2004)
Kommentar
Fra : Ulrik Magnusson


Dato : 01-02-04 14:31



Soren Kuula wrote:

> public static void main (String[] args) {
> General a = new General();
> Special b = new Special();
> General c = b;
>
> a.method(a);
> a.method(b);
> a.method(c);
> }
> }
>
> Hmmmm.. havde helt glemt at Java bandt metodekaldene så tidligt.

Jep, den erklærede type bruges. Eksemplet kan vel reduceres til

public static void main (String[] args) {
General a = new General();
General b = new Special();
a.method(a);
a.method(b);
}

- og det er vel ikke så god stil at have et hierarki i sine
metodeerklæringer,
men nok ikke noget man tænker over så tit..


> Super() {
> init();
> }
>
> void init() {
> System.out.println("Nice air up here");
> }

Det synes jeg er fy fy - man skal generelt passe på med at kalde
ikke-final-og-ikke-
private metoder internt - ikke-final-og-ikke-private metoder er netop
ikke-final-OG-ikke-private fordi de _både_ skal kunne bruges fra andre
klasser _og_
kunne omdefineres - og en subklasse kan altså omdefinere en forælderklasses
interne
virkemåde, uff..

Good stuff - kom med flere faldgruber, som man ikke liger tænker over til
daglig.

Ulrik Magnusson


Jonas Kongslund (02-02-2004)
Kommentar
Fra : Jonas Kongslund


Dato : 02-02-04 00:05

Ulrik Magnusson wrote:
> Good stuff - kom med flere faldgruber, som man ikke liger tænker over til
> daglig.

Hvad sker der når man oversætter og afvikler Outer i nedenstående program?

Filen *Outer.java*
1. class Outer {
2. public static void main(String args[]) {
3. Outer o = new Outer();
4. Inner i = o.new Inner();
5. }
6. class Inner extends Super {
7. Inner () {
8. method();
9. }
10. void method() {
11. System.out.println(Outer.this.method());
12. }
13. }
14. String method() { return "foo"; }
15. }
16. abstract class Super {
17. Super() {
18. method();
19. }
20. abstract void method();
21. }

=================

Er der noget til hinder for at nedenstående program ikke kan oversættes?

Filen *Outer.java*
1. package p1;
2. public class Outer {
3. protected class Inner{}
4. }

Filen *SonOfOuter.java*
1. package p2;
2. class SonOfOuter extends p1.Outer {
3. void foo() {
4. new Inner();
5. }
6. }

--
Jonas Kongslund

Ulrik Magnusson (02-02-2004)
Kommentar
Fra : Ulrik Magnusson


Dato : 02-02-04 17:20



Jonas Kongslund wrote:

> Hvad sker der når man oversætter og afvikler Outer i nedenstående program?
>
> 16. abstract class Super {
> 17. Super() {
> 18. method();
> 19. }
> 20. abstract void method();

Internt kald af ikke-private-og-ikke-final metode - det går ski altid galt..
I dette tilfælde helt katastrofalt, da det er i konstruktoren, som kaldes
før "this" i barneklasser oprettes.

> Er der noget til hinder for at nedenstående program ikke kan oversættes?

heh, åbenbart - er dette en fejl i javac, eller hvad? Jeg kunne ikke lige finde

noget i JLS om specialbehandling af protected mht indre klasser.

Ulrik Magnusson


Soren Kuula (02-02-2004)
Kommentar
Fra : Soren Kuula


Dato : 02-02-04 18:11

Hej nø(r/d)der,

>
>>Hvad sker der når man oversætter og afvikler Outer i nedenstående program?
>>
>>16. abstract class Super {
>>17. Super() {
>>18. method();
>>19. }
>>20. abstract void method();
>
>
> Internt kald af ikke-private-og-ikke-final metode - det går ski altid galt..
> I dette tilfælde helt katastrofalt, da det er i konstruktoren, som kaldes
> før "this" i barneklasser oprettes.

Den ER cool. Er der ikke tale om at Inners reference til det omsluttende
Outer object ikke er initieret i det øjeblik Outers konstrudstor -
indirekte - vil kalde en metode i Outer ?

>>Er der noget til hinder for at nedenstående program ikke kan oversættes?
>
>
> heh, åbenbart - er dette en fejl i javac, eller hvad? Jeg kunne ikke lige finde
>
> noget i JLS om specialbehandling af protected mht indre klasser.

Default constructoren arver access right fra klassens, har jeg nu set et
sted. Det vidste jeg da slet ikke.

Qualit¨at !

MVH
Søren
--
Fjern de 4 bogstaver i min mailadresse som er indsat for at hindre s...
Remove the 4 letter word meaning "junk mail" in my mail address.


Ulrik Magnusson (02-02-2004)
Kommentar
Fra : Ulrik Magnusson


Dato : 02-02-04 18:25



Soren Kuula wrote:

> Hej nø(r/d)der,
>
> >
> >>Hvad sker der når man oversætter og afvikler Outer i nedenstående program?
> >>
> >>16. abstract class Super {
> >>17. Super() {
> >>18. method();
> >>19. }
> >>20. abstract void method();
> >
> >
> > Internt kald af ikke-private-og-ikke-final metode - det går ski altid galt..
> > I dette tilfælde helt katastrofalt, da det er i konstruktoren, som kaldes
> > før "this" i barneklasser oprettes.
>
> Den ER cool. Er der ikke tale om at Inners reference til det omsluttende
> Outer object ikke er initieret i det øjeblik Outers konstrudstor -
> indirekte - vil kalde en metode i Outer ?

Netop - this er først legal når forælderklassens konstruktor er kaldt -
fx er nedenstående ikke ok, men fanges af javac:

class Example
{
Example( Object s )
{
}
}

class SubExample
extends Example
{
SubExample()
{
super( foo() );
}

SubExample( Object dummy )
{
super( this );
}

final String foo()
{
return "42";
}
}

- javac siger:

"C:\Example.java:16: cannot reference this before supertype constructor has been
called
super( foo() );
^
C:\Example.java:21: cannot reference this before supertype constructor has been
called
super( this );
^
2 errors

2 error(s)"


> > heh, åbenbart - er dette en fejl i javac, eller hvad? Jeg kunne ikke lige finde
> > noget i JLS om specialbehandling af protected mht indre klasser.
>
> Default constructoren arver access right fra klassens, har jeg nu set et
> sted. Det vidste jeg da slet ikke.

Men p1.Outer.Inner er jo protected, og så burde klasser i samme package samt
"barneklasser" (fx p2.SonOfOuter) jo have adgang.. hmm

Ulrik Magnusson


Jonas Kongslund (02-02-2004)
Kommentar
Fra : Jonas Kongslund


Dato : 02-02-04 20:51

Soren Kuula wrote:
> Den ER cool. Er der ikke tale om at Inners reference til det omsluttende
> Outer object ikke er initieret i det øjeblik Outers konstrudstor -
> indirekte - vil kalde en metode i Outer ?

Jo, bortset fra at du mener "Supers konstruktør" frem for "Outers
konstrudstor".

--
Jonas Kongslund

Jonas Kongslund (02-02-2004)
Kommentar
Fra : Jonas Kongslund


Dato : 02-02-04 20:31

Ulrik Magnusson wrote:
> heh, åbenbart - er dette en fejl i javac, eller hvad? Jeg kunne ikke lige
> finde noget i JLS om specialbehandling af protected mht indre klasser.

Lige præcis det eksempel nappede jeg fra JLS'en for et par måneder siden.
Her følger det relevante afsnit fra §8.8.7 (Default Constructor):

"The constructor for Inner is protected. However, the constructor is
protected relative to Inner, while Inner is protected relative to
Outer. So, Inner is accessible in SonOfOuter, since it is a subclass
of Outer. Inner's constructor is not accessible in SonOfOuter, because
the class SonOfOuter is not a subclass of Inner! Hence, even though
Inner is accessible, its default constructor is not."

--
Jonas Kongslund

Ulrik Magnusson (02-02-2004)
Kommentar
Fra : Ulrik Magnusson


Dato : 02-02-04 22:22



Jonas Kongslund wrote:

> Ulrik Magnusson wrote:
> > heh, åbenbart - er dette en fejl i javac, eller hvad? Jeg kunne ikke lige
> > finde noget i JLS om specialbehandling af protected mht indre klasser.
>
> Lige præcis det eksempel nappede jeg fra JLS'en for et par måneder siden.
> Her følger det relevante afsnit fra §8.8.7 (Default Constructor):
>
> "The constructor for Inner is protected. However, the constructor is
> protected relative to Inner, while Inner is protected relative to
> Outer. So, Inner is accessible in SonOfOuter, since it is a subclass
> of Outer. Inner's constructor is not accessible in SonOfOuter, because
> the class SonOfOuter is not a subclass of Inner! Hence, even though
> Inner is accessible, its default constructor is not."

hehe, hvor grotesk - dette får det til at virke:

package p1;
public class Outer
{
protected static class Inner
{
public Inner()
{}
}
}

- og det gælder ikke kun default konstruktor - heller ikke andre
konstruktors, protected static metoder og static medlemsvariabler
er der adgang til. Hmm.. det kunne de godt have skrevet med
lidt større fontstørrelse i JLS - det er stadig ikke lykkedes mig
at finde andet end ovenstående, som tilsyneladende kun gælder
default konstruktor, hvis man ikke lige læser det der står med
usynligt blæk.

Ulrik Magnusson


Ulrik Magnusson (02-02-2004)
Kommentar
Fra : Ulrik Magnusson


Dato : 02-02-04 22:30



Ulrik Magnusson wrote:

> - og det gælder ikke kun default konstruktor - heller ikke andre
> konstruktors, protected static metoder og static medlemsvariabler
> er der adgang til.

- og ikke kun static, også ikke-static:

package p1;
public class Outer
{
protected class Inner
{
protected void foo()
{
System.out.println("Goddaw do.");
}
}
public Inner getInner()
{
return new Inner();
}
}

package p2;
class SonOfOuter extends p1.Outer
{
void foo()
{
getInner().foo();
}
}

Ulrik Magnusson


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

Månedens bedste
Årets bedste
Sidste års bedste