Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #33277 > unrolled thread
| Started by | regis <regis.barbanchon@free.fr> |
|---|---|
| First post | 2015-12-03 00:40 +0100 |
| Last post | 2015-12-03 08:06 -0500 |
| Articles | 14 — 6 participants |
Back to article view | Back to comp.lang.java.programmer
about class dependancies regis <regis.barbanchon@free.fr> - 2015-12-03 00:40 +0100
Re: about class dependancies Lew <lewbloch@gmail.com> - 2015-12-02 16:32 -0800
Re: about class dependancies regis <regis.barbanchon@free.fr> - 2015-12-03 01:49 +0100
Re: about class dependancies regis <regis.barbanchon@free.fr> - 2015-12-03 02:26 +0100
Re: about class dependancies Arne Vajhøj <arne@vajhoej.dk> - 2015-12-02 21:55 -0500
Re: about class dependancies Arne Vajhøj <arne@vajhoej.dk> - 2015-12-02 21:58 -0500
Re: about class dependancies Steven Simpson <ss@my.domain.invalid> - 2015-12-03 15:15 +0000
Re: about class dependancies Arne Vajhøj <arne@vajhoej.dk> - 2015-12-03 19:49 -0500
Re: about class dependancies Lew <lewbloch@gmail.com> - 2015-12-16 18:27 -0800
Re: about class dependancies Steven Simpson <ss@my.domain.invalid> - 2015-12-17 08:39 +0000
Re: about class dependancies Lew <lewbloch@gmail.com> - 2015-12-17 13:36 -0800
Re: about class dependancies Mike Amling <mamling@chaff.us> - 2015-12-21 08:29 -0600
Re: about class dependancies regis <regis.barbanchon@free.fr> - 2015-12-03 02:07 +0100
Re: about class dependancies Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-12-03 08:06 -0500
| From | regis <regis.barbanchon@free.fr> |
|---|---|
| Date | 2015-12-03 00:40 +0100 |
| Subject | about class dependancies |
| Message-ID | <565f816b$0$3054$426a74cc@news.free.fr> |
Greetings,
let say we have some public class A
that depends on some public class B, e.g.:
====
// B.java
public class B {
public int f(int n) { return 2*n; }
}
====
// A.java
public class A {
public static void main (String[] args) {
B b= new B ();
System.out.println (b.f(5));
}
}
====
$ javac A.java B.java
$ java A
10
====
Then let say class B changes (with signature of f() unchanged), e.g.:
====
// B.java, changed
public class B {
int lambda= 10;
public int f(int n) { return lambda*n; }
}
====
Finally, we update file B.class, but not file A.class,
====
$ javac B.java # but not A.java
$ java A
50
====
It seems to work, but is it guaranteed ?
or should file A.class still be updated ?
Thanks,
Regis
[toc] | [next] | [standalone]
| From | Lew <lewbloch@gmail.com> |
|---|---|
| Date | 2015-12-02 16:32 -0800 |
| Message-ID | <77dedcc2-f07c-4234-9b5c-22993b04c6d1@googlegroups.com> |
| In reply to | #33277 |
On Wednesday, December 2, 2015 at 3:40:46 PM UTC-8, regis wrote:
> Greetings,
>
> let say we have some public class A
> that depends on some public class B, e.g.:
>
> ====
> // B.java
> public class B {
> public int f(int n) { return 2*n; }
> }
> ====
> // A.java
> public class A {
> public static void main (String[] args) {
> B b= new B ();
> System.out.println (b.f(5));
> }
> }
> ====
> $ javac A.java B.java
> $ java A
> 10
> ====
>
> Then let say class B changes (with signature of f() unchanged), e.g.:
>
> ====
> // B.java, changed
> public class B {
> int lambda= 10;
> public int f(int n) { return lambda*n; }
> }
> ====
>
> Finally, we update file B.class, but not file A.class,
>
> ====
> $ javac B.java # but not A.java
> $ java A
> 50
> ====
>
> It seems to work, but is it guaranteed ?
> or should file A.class still be updated ?
The Java compiler "javac" is smart enough to resolve many dependencies, including the one you note here. However, this would not work if 'lambda' (*terrible* name for that variable!) were made 'final', and therefore a constant variable.
--
Lew
[toc] | [prev] | [next] | [standalone]
| From | regis <regis.barbanchon@free.fr> |
|---|---|
| Date | 2015-12-03 01:49 +0100 |
| Message-ID | <565f9194$0$4565$426a74cc@news.free.fr> |
| In reply to | #33280 |
On 12/03/15 01:32, Lew wrote:
> On Wednesday, December 2, 2015 at 3:40:46 PM UTC-8, regis wrote:
>> Greetings,
>>
>> let say we have some public class A
>> that depends on some public class B, e.g.:
>>
>> ====
>> // B.java
>> public class B {
>> public int f(int n) { return 2*n; }
>> }
>> ====
>> // A.java
>> public class A {
>> public static void main (String[] args) {
>> B b= new B ();
>> System.out.println (b.f(5));
>> }
>> }
>> ====
>> $ javac A.java B.java
>> $ java A
>> 10
>> ====
>>
>> Then let say class B changes (with signature of f() unchanged), e.g.:
>>
>> ====
>> // B.java, changed
>> public class B {
>> int lambda= 10;
>> public int f(int n) { return lambda*n; }
>> }
>> ====
>>
>> Finally, we update file B.class, but not file A.class,
>>
>> ====
>> $ javac B.java # but not A.java
>> $ java A
>> 50
>> ====
>>
>> It seems to work, but is it guaranteed ?
>> or should file A.class still be updated ?
> The Java compiler "javac" is smart enough to resolve many dependencies, including the one you note here.
> However, this would not work if 'lambda' (*terrible* name for that variable!) were made 'final', and therefore a constant variable.
It still seems to work if it is made final...
// B.java, changed
public class B {
final int multiplier= 1000;
public int f(int n) { return multiplier*n; }
}
====
$ javac B.java # but not A.java
$ java A
5000
[toc] | [prev] | [next] | [standalone]
| From | regis <regis.barbanchon@free.fr> |
|---|---|
| Date | 2015-12-03 02:26 +0100 |
| Message-ID | <565f9a2e$0$3878$426a74cc@news.free.fr> |
| In reply to | #33281 |
On 12/03/15 02:05, Stefan Ram wrote:
> regis <regis.barbanchon@free.fr> writes:
>> It still seems to work if it is made final...
>
> echo >A.java public final class A { public static void main( final java.lang.String[] args ){ java.lang.System.out.println( B.x ); }}
> echo >B.java public final class B { public static final int x = 1; }
> javac A.java
> javac B.java
> java A
> RENAME A.class hide.class
> echo >B.java public final class B { public static final int x = 2; }
> javac B.java
> DELETE A.class
> RENAME hide.class A.class
> java A
>
> Now it still prints 1, not 2.
>
> The above script assume Microsoft® Windows.
> You might have to adjust it for your environment.
Ah, interesting...
so a non-updated file A.class can indeed be tricked by a change in B...
Thanks for that one.
===
// B.java
public class B {
static final int multiplier= 10;
public int f(int n) { return multiplier*n; }
}
===
// A.java
public class A {
public static void main (String[] args) {
B b= new B ();
System.out.printf ("%d * 5 = %d\n", b.multiplier, b.f(5));
}
}
===
$ javac A.java B.java
$ java A
10 * 5 = 50
===
// B.java, changed
public class B {
static final int multiplier= 1000;
public int f(int n) { return multiplier*n; }
}
===
$ javac B.java # but not A.java
$ java A
10 * 5 = 5000
===
(I would be interested if anyone knows other simple ways
to make A break with a change in B...)
[toc] | [prev] | [next] | [standalone]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2015-12-02 21:55 -0500 |
| Message-ID | <n3oauh$pgf$1@speranza.aioe.org> |
| In reply to | #33285 |
On 12/2/2015 8:26 PM, regis wrote:
> On 12/03/15 02:05, Stefan Ram wrote:
>> regis <regis.barbanchon@free.fr> writes:
>>> It still seems to work if it is made final...
>>
>> echo >A.java public final class A { public static void main( final
>> java.lang.String[] args ){ java.lang.System.out.println( B.x ); }}
>> echo >B.java public final class B { public static final int x = 1; }
>> javac A.java
>> javac B.java
>> java A
>> RENAME A.class hide.class
>> echo >B.java public final class B { public static final int x = 2; }
>> javac B.java
>> DELETE A.class
>> RENAME hide.class A.class
>> java A
>>
>> Now it still prints 1, not 2.
>>
>> The above script assume Microsoft® Windows.
>> You might have to adjust it for your environment.
>
> Ah, interesting...
> so a non-updated file A.class can indeed be tricked by a change in B...
What is happening is seen with this:
public class B {
public static final int K = 123;
}
public class A {
public static void main(String[] args) {
System.out.println(B.K);
System.out.println(123);
}
}
C:\Work>javap -c A
Compiled from "A.java"
public class A {
public A();
Code:
0: aload_0
1: invokespecial #1 // Method
java/lang/Object."init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #2 // Field
java/lang/System.out:Ljava/io/PrintStream;
3: bipush 123
5: invokevirtual #4 // Method
java/io/PrintStream.println:(I)V
8: getstatic #2 // Field
java/lang/System.out:Ljava/io/PrintStream;
11: bipush 123
13: invokevirtual #4 // Method
java/io/PrintStream.println:(I)V
16: return
}
A.class does not contain a named reference to B.K instead
A.class contains the while of B.K from the time of compilation.
Arne
[toc] | [prev] | [next] | [standalone]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2015-12-02 21:58 -0500 |
| Message-ID | <n3ob3v$pgf$2@speranza.aioe.org> |
| In reply to | #33286 |
On 12/2/2015 9:55 PM, Arne Vajhøj wrote:
> On 12/2/2015 8:26 PM, regis wrote:
>> On 12/03/15 02:05, Stefan Ram wrote:
>>> regis <regis.barbanchon@free.fr> writes:
>>>> It still seems to work if it is made final...
>>>
>>> echo >A.java public final class A { public static void main( final
>>> java.lang.String[] args ){ java.lang.System.out.println( B.x ); }}
>>> echo >B.java public final class B { public static final int x = 1; }
>>> javac A.java
>>> javac B.java
>>> java A
>>> RENAME A.class hide.class
>>> echo >B.java public final class B { public static final int x = 2; }
>>> javac B.java
>>> DELETE A.class
>>> RENAME hide.class A.class
>>> java A
>>>
>>> Now it still prints 1, not 2.
>>>
>>> The above script assume Microsoft® Windows.
>>> You might have to adjust it for your environment.
>>
>> Ah, interesting...
>> so a non-updated file A.class can indeed be tricked by a change in B...
>
> What is happening is seen with this:
>
> public class B {
> public static final int K = 123;
> }
>
> public class A {
> public static void main(String[] args) {
> System.out.println(B.K);
> System.out.println(123);
> }
> }
>
> C:\Work>javap -c A
> Compiled from "A.java"
> public class A {
> public A();
> Code:
> 0: aload_0
> 1: invokespecial #1 // Method
> java/lang/Object."init>":()V
> 4: return
>
> public static void main(java.lang.String[]);
> Code:
> 0: getstatic #2 // Field
> java/lang/System.out:Ljava/io/PrintStream;
> 3: bipush 123
> 5: invokevirtual #4 // Method
> java/io/PrintStream.println:(I)V
> 8: getstatic #2 // Field
> java/lang/System.out:Ljava/io/PrintStream;
> 11: bipush 123
> 13: invokevirtual #4 // Method
> java/io/PrintStream.println:(I)V
> 16: return
> }
>
> A.class does not contain a named reference to B.K instead
> A.class contains the while of B.K from the time of compilation.
Note that the practical impact of this is close to zero.
Practically everyone starts a Java build by deleting all the
previously build class files.
Arne
[toc] | [prev] | [next] | [standalone]
| From | Steven Simpson <ss@my.domain.invalid> |
|---|---|
| Date | 2015-12-03 15:15 +0000 |
| Message-ID | <mt26jc-oi8.ln1@s.simpson148.btinternet.com> |
| In reply to | #33285 |
On 03/12/15 01:26, regis wrote: > (I would be interested if anyone knows other simple ways > to make A break with a change in B...) A calls B.f, but doesn't use the return value, and then B.f's return type changes. Like the in-lined constant, A.java doesn't have to change, but it does have to be recompiled, because the return type is part of the method's identifier that A.class uses to refer to B. -- ss at comp dot lancs dot ac dot uk
[toc] | [prev] | [next] | [standalone]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2015-12-03 19:49 -0500 |
| Message-ID | <n3qnug$7ch$1@speranza.aioe.org> |
| In reply to | #33290 |
On 12/3/2015 10:15 AM, Steven Simpson wrote: > On 03/12/15 01:26, regis wrote: >> (I would be interested if anyone knows other simple ways >> to make A break with a change in B...) > > A calls B.f, but doesn't use the return value, and then B.f's return > type changes. Like the in-lined constant, A.java doesn't have to > change, but it does have to be recompiled, because the return type is > part of the method's identifier that A.class uses to refer to B. But unlike the changed constant problem this should give a runtime exception. Arne
[toc] | [prev] | [next] | [standalone]
| From | Lew <lewbloch@gmail.com> |
|---|---|
| Date | 2015-12-16 18:27 -0800 |
| Message-ID | <31f29220-8f05-42a4-b62e-59eec378b924@googlegroups.com> |
| In reply to | #33281 |
On Wednesday, December 2, 2015 at 4:49:41 PM UTC-8, regis wrote:
> On 12/03/15 01:32, Lew wrote:
> > On Wednesday, December 2, 2015 at 3:40:46 PM UTC-8, regis wrote:
> >> Greetings,
> >>
> >> let say we have some public class A
> >> that depends on some public class B, e.g.:
> >>
> >> ====
> >> // B.java
> >> public class B {
> >> public int f(int n) { return 2*n; }
> >> }
> >> ====
> >> // A.java
> >> public class A {
> >> public static void main (String[] args) {
> >> B b= new B ();
> >> System.out.println (b.f(5));
> >> }
> >> }
> >> ====
> >> $ javac A.java B.java
> >> $ java A
> >> 10
> >> ====
> >>
> >> Then let say class B changes (with signature of f() unchanged), e.g.:
> >>
> >> ====
> >> // B.java, changed
> >> public class B {
> >> int lambda= 10;
> >> public int f(int n) { return lambda*n; }
> >> }
> >> ====
> >>
> >> Finally, we update file B.class, but not file A.class,
> >>
> >> ====
> >> $ javac B.java # but not A.java
> >> $ java A
> >> 50
> >> ====
> >>
> >> It seems to work, but is it guaranteed ?
> >> or should file A.class still be updated ?
>
>
> > The Java compiler "javac" is smart enough to resolve many dependencies, including the one you note here.
> > However, this would not work if 'lambda' (*terrible* name for that variable!) were made 'final', and therefore a constant variable.
>
>
> It still seems to work if it is made final...
>
> // B.java, changed
> public class B {
> final int multiplier= 1000;
> public int f(int n) { return multiplier*n; }
> }
> ====
> $ javac B.java # but not A.java
> $ java A
> 5000
That isn't what I meant. I meant if you recompile 'A' but not 'B" then you don't pick up the change in 'B'. What you did was recompile 'B' and run 'A'. I had misread your example.
--
Lew
[toc] | [prev] | [next] | [standalone]
| From | Steven Simpson <ss@my.domain.invalid> |
|---|---|
| Date | 2015-12-17 08:39 +0000 |
| Message-ID | <bu8akc-reu.ln1@s.simpson148.btinternet.com> |
| In reply to | #33358 |
On 17/12/15 02:27, Lew wrote:
> On Wednesday, December 2, 2015 at 4:49:41 PM UTC-8, regis wrote:
>> On 12/03/15 01:32, Lew wrote:
>>> On Wednesday, December 2, 2015 at 3:40:46 PM UTC-8, regis wrote:
>>>> let say we have some public class A
>>>> that depends on some public class B, e.g.:
>>>>
>>>> ====
>>>> // B.java
>>>> public class B {
>>>> public int f(int n) { return 2*n; }
>>>> }
>>>> ====
>>>> // A.java
>>>> public class A {
>>>> public static void main (String[] args) {
>>>> B b= new B ();
>>>> System.out.println (b.f(5));
>>>> }
>>>> }
>>>> ====
>>>> $ javac A.java B.java
>>>> $ java A
>>>> 10
>>>> ====
>>>>
>>>> Then let say class B changes (with signature of f() unchanged), e.g.:
>>>>
>>>> ====
>>>> // B.java, changed
>>>> public class B {
>>>> int lambda= 10;
>>>> public int f(int n) { return lambda*n; }
>>>> }
>>>> ====
>>>>
>>>> Finally, we update file B.class, but not file A.class,
>>>>
>>>> ====
>>>> $ javac B.java # but not A.java
>>>> $ java A
>>>> 50
>>>> ====
>>>>
>>>> It seems to work, but is it guaranteed ?
>>>> or should file A.class still be updated ?
>>
>>> The Java compiler "javac" is smart enough to resolve many dependencies, including the one you note here.
>>> However, this would not work if 'lambda' (*terrible* name for that variable!) were made 'final', and therefore a constant variable.
>>
>> It still seems to work if it is made final...
>>
>> // B.java, changed
>> public class B {
>> final int multiplier= 1000;
>> public int f(int n) { return multiplier*n; }
>> }
>> ====
>> $ javac B.java # but not A.java
>> $ java A
>> 5000
> That isn't what I meant. I meant if you recompile 'A' but not 'B" then you don't pick up the change in 'B'. What you did was recompile 'B' and run 'A'. I had misread your example.
I don't get it. A.java refers to B, so compiling A.java will also
compile B.java as an implicit class, unless you have implicit
compilation turned off.
--
ss at comp dot lancs dot ac dot uk
[toc] | [prev] | [next] | [standalone]
| From | Lew <lewbloch@gmail.com> |
|---|---|
| Date | 2015-12-17 13:36 -0800 |
| Message-ID | <5fa6a8a6-389b-4ed0-ae37-941d5fd6d358@googlegroups.com> |
| In reply to | #33361 |
On Thursday, December 17, 2015 at 12:45:27 AM UTC-8, Steven Simpson wrote:
> On 17/12/15 02:27, Lew wrote:
> > On Wednesday, December 2, 2015 at 4:49:41 PM UTC-8, regis wrote:
> >> On 12/03/15 01:32, Lew wrote:
> >>> On Wednesday, December 2, 2015 at 3:40:46 PM UTC-8, regis wrote:
> >>>> let say we have some public class A
> >>>> that depends on some public class B, e.g.:
> >>>>
> >>>> ====
> >>>> // B.java
> >>>> public class B {
> >>>> public int f(int n) { return 2*n; }
> >>>> }
> >>>> ====
> >>>> // A.java
> >>>> public class A {
> >>>> public static void main (String[] args) {
> >>>> B b= new B ();
> >>>> System.out.println (b.f(5));
> >>>> }
> >>>> }
> >>>> ====
> >>>> $ javac A.java B.java
> >>>> $ java A
> >>>> 10
> >>>> ====
> >>>>
> >>>> Then let say class B changes (with signature of f() unchanged), e.g.:
> >>>>
> >>>> ====
> >>>> // B.java, changed
> >>>> public class B {
> >>>> int lambda= 10;
> >>>> public int f(int n) { return lambda*n; }
> >>>> }
> >>>> ====
> >>>>
> >>>> Finally, we update file B.class, but not file A.class,
> >>>>
> >>>> ====
> >>>> $ javac B.java # but not A.java
> >>>> $ java A
> >>>> 50
> >>>> ====
> >>>>
> >>>> It seems to work, but is it guaranteed ?
> >>>> or should file A.class still be updated ?
> >>
> >>> The Java compiler "javac" is smart enough to resolve many dependencies, including the one you note here.
> >>> However, this would not work if 'lambda' (*terrible* name for that variable!) were made 'final', and therefore a constant variable.
> >>
> >> It still seems to work if it is made final...
> >>
> >> // B.java, changed
> >> public class B {
> >> final int multiplier= 1000;
> >> public int f(int n) { return multiplier*n; }
> >> }
> >> ====
> >> $ javac B.java # but not A.java
> >> $ java A
> >> 5000
> > That isn't what I meant. I meant if you recompile 'A' but not 'B" then you don't pick up the change in 'B'. What you did was recompile 'B' and run 'A'. I had misread your example.
>
> I don't get it. A.java refers to B, so compiling A.java will also
> compile B.java as an implicit class, unless you have implicit
> compilation turned off.
Yeah, my mistake. Let me try to get it right this time.
You define a constant variable in B and refer to it from A.
You recompile B with a different constant value.
You then run A without recompiling it. Magically, it refers to the old value of the B constant.
Because the constant was inlined in A, it stopped looking like a variable, so the runtime linkage doesn't refer to the constant from B, but uses the inlined value already in A.
http://javasplitter.blogspot.com/2011/10/static-final-inline-trap.html
I apologize for the confusion.
--
Lew
[toc] | [prev] | [next] | [standalone]
| From | Mike Amling <mamling@chaff.us> |
|---|---|
| Date | 2015-12-21 08:29 -0600 |
| Message-ID | <n59255$6ve$1@dont-email.me> |
| In reply to | #33364 |
On 12/17/15 3:36 PM, Lew wrote:
>
> You define a constant variable in B and refer to it from A.
>
> You recompile B with a different constant value.
>
> You then run A without recompiling it. Magically, it refers to the old value of the B constant.
>
> Because the constant was inlined in A, it stopped looking like a variable, so the runtime linkage doesn't refer to the constant from B, but uses the inlined value already in A.
> http://javasplitter.blogspot.com/2011/10/static-final-inline-trap.html
I've seen Java software use this to ensure that the components in use
are consistent. E.g.,
class A {
public static final int VERSION=3;
public int getVersion() {
return VERSION;
}
}
class B {
public static void main(String[] args) {
if (A.getVersion() // The version we're running with
!=A.VERSION) { // The version we were compiled with
uhoh();
}
}
}
Mike Amling
--
QnV0IEkgZG9uJ3QgcmVjYWxsIHdoYXQgcHJvZ3JhbSBJIHNhdyB0aGlzIGluLg==
[toc] | [prev] | [next] | [standalone]
| From | regis <regis.barbanchon@free.fr> |
|---|---|
| Date | 2015-12-03 02:07 +0100 |
| Message-ID | <565f95e3$0$4574$426a74cc@news.free.fr> |
| In reply to | #33277 |
On 12/03/15 01:12, Stefan Ram wrote:
> regis <regis.barbanchon@free.fr> writes:
>> public class B {
>
> The Byte Code contains symbols that AFAIK refer to the
> class and the methods /by name/. There is no other magical
> link or internal versioning. So it should be legal as long
> as the interface is the same.
>
> With
>
> javap -verbose A
>
> , you can see the symbol table of class A.
>
so as long as f() signature is untouched,
no amount of change in B will make a non-updated A.class to break ?
including:
- adding/removing members, static member, final members
- changing a final member's values,
- adding/removing methods other than f(),
- changing f()'s body.
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2015-12-03 08:06 -0500 |
| Message-ID | <n3pel2$rs8$1@dont-email.me> |
| In reply to | #33283 |
On 12/2/2015 8:07 PM, regis wrote:
> On 12/03/15 01:12, Stefan Ram wrote:
>> regis <regis.barbanchon@free.fr> writes:
>>> public class B {
>>
>> The Byte Code contains symbols that AFAIK refer to the
>> class and the methods /by name/. There is no other magical
>> link or internal versioning. So it should be legal as long
>> as the interface is the same.
>>
>> With
>>
>> javap -verbose A
>>
>> , you can see the symbol table of class A.
>>
>
> so as long as f() signature is untouched,
> no amount of change in B will make a non-updated A.class to break ?
> including:
> - adding/removing members, static member, final members
> - changing a final member's values,
> - adding/removing methods other than f(),
> - changing f()'s body.
None of these will change the way A refers to B's f(). If you
saved the old A.class and recompiled A to make a fresh one, the byte
code would be unchanged. (Some non-executable metadata like date
stamps might be, but all of A's fields, methods, and so on would
be the same as before.)
Some of the changes you mention would invalidate A.class if A
made other kinds of references to B. For example, if A also calls
B's g() method and you remove g() or make it private, A.class won't
work any more.
--
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.java.programmer
csiph-web