|
| 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
| |
|
|