Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > borrowing Constants

Reply
Thread Tools

borrowing Constants

 
 
Lew
Guest
Posts: n/a
 
      09-24-2011
Lew wrote:
> Roedy Green wrote:
>> When you use Class B, does all of class A get instantiated?

>
> Strictly speaking, and I am fairly sure you don't mean this, a class withonly static members might never, or cannot ever be instantiated (dependingon the use of certain idioms).
>
> As you know, I favor exactitude, some think colo-rectitude in certain terminologies.
> It cuts both ways - I have to relearn terms when I have them wrong.


For example, Roedy correctly points out that classes do have a class objectthat instantiates when they load.

There are two main stages to the usefulness of a type at runtime. One is load, the other initialize. They're like two steps in each class's private Big Bang of creation.

A class loads among other things upon reference to that class's instance variable, pointed to by the 'class' attribute. Under that particular circumstance it does not also initialize. That happens under non-pathological references to classes, such as access to behaviors or contents through their members. ('class' is not a member.) 'final' fields, especially 'static' ones, most especially compile-time constant variables, get special treatment in the initialization.

I'll stop now.

--
Lew
 
Reply With Quote
 
 
 
 
Arne Vajh°j
Guest
Posts: n/a
 
      09-24-2011
On 9/23/2011 9:10 PM, Arved Sandstrom wrote:
> On 11-09-23 09:44 PM, Arne Vajh°j wrote:
>> On 9/23/2011 8:40 PM, Roedy Green wrote:
>>> If you have some code like this:
>>>
>>> class A
>>> {
>>> static String VERSION = "1.0b";
>>> }
>>>
>>> and
>>> class B
>>> {
>>> static String VERSION = A.VERSION;
>>> }
>>>
>>> When you use Class B, does all of class A get instantiated?

>>
>> I don't think it can just initialize what is needed.
>>
>> The overhead must be microscopic anyway.
>>
>>> Does all of class A get put in B's jar?

>>
>> That depends on the one doing the "putting".
>>
>>> If so, it suggests you are better off to have a tiny common class and
>>> have A and B reference it.

>>
>> You should stick to good design and keep the versions where they
>> logical belong.


> Which logical place is not in the code at all. Granted, I don't know
> that Roedy's example is doing anything more than using "VERSION" as a
> generic variable name (I hope).
>
> I'm not going to be unyielding on this, but I have personally never
> encountered or read of any situation where source code needed to be
> annotated with configuration or version control information. This
> includes the RCS-style keywords; the argument is that these help if a
> file is exported outside the development environment, but that's not a
> compelling argument for me.


A version number hardcoded in source code will at some point in time
get out of synch with the actual version number.

Arne

 
Reply With Quote
 
 
 
 
Arne Vajh°j
Guest
Posts: n/a
 
      09-24-2011
On 9/23/2011 9:44 PM, markspace wrote:
> On 9/23/2011 5:40 PM, Roedy Green wrote:
>> When you use Class B, does all of class A get instantiated?
>> Does all of class A get put in B's jar?

>
> I think so, yes. Not "instantiated" as others pointed out but
> initialized. But yes, regardless.
>
> I believe you can get around this by making VERSION final. The compiler
> is allowed (possibly required?) to copy final static values as a kind of
> constant, in order to avoid this kind of unneeded initialization.
>
> class A
> {
> static final String VERSION = "1.0b";
> }


But that introduces the risk of B not being updated when
A is updated.

Arne


 
Reply With Quote
 
Volker Borchert
Guest
Posts: n/a
 
      09-24-2011
Roedy Green wrote:
> If you have some code like this:
>
> class A
> {
> static String VERSION = "1.0b";
> }
>
> and
> class B
> {
> static String VERSION = A.VERSION;
> }
>
> When you use Class B, does all of class A get instantiated?
> Does all of class A get put in B's jar?


If they're Constants, they should be final, and then the compiler
would "inline" the string into B's constant pool.

--

"I'm a doctor, not a mechanic." Dr Leonard McCoy <(E-Mail Removed)>
"I'm a mechanic, not a doctor." Volker Borchert <(E-Mail Removed)>
 
Reply With Quote
 
Roedy Green
Guest
Posts: n/a
 
      09-24-2011
On Fri, 23 Sep 2011 17:40:20 -0700, Roedy Green
<(E-Mail Removed)> wrote, quoted or indirectly quoted
someone who said :

>class A
>{
> static String VERSION = "1.0b";
>}
>
>and
>class B
>{
>static String VERSION = A.VERSION;
>}


if I change that to

>class A
>{
> static final String VERSION = "1.0b";
>}
>
>and
>class B
>{
>static final String VERSION = A.VERSION;
>}


I understand from Lew that effectively decouples the classes. A will
not necessarily appear in B's jar. A will not be loaded when B is
initialised.


--
Roedy Green Canadian Mind Products
http://mindprod.com
It should not be considered an error when the user starts something
already started or stops something already stopped. This applies
to browsers, services, editors... It is inexcusable to
punish the user by requiring some elaborate sequence to atone,
e.g. open the task editor, find and kill some processes.

 
Reply With Quote
 
Roedy Green
Guest
Posts: n/a
 
      09-25-2011
On Fri, 23 Sep 2011 17:40:20 -0700, Roedy Green
<(E-Mail Removed)> wrote, quoted or indirectly quoted
someone who said :

>class A
>{
> static String VERSION = "1.0b";
>}
>
>and
>class B
>{
>static String VERSION = A.VERSION;
>}


restating, if the expression for A.VERSION cannot be evaluated an
compile time, even final won't rescue you from having to include both
A in your jar and indirectly loading A when you load B.

So the rule of thumb use static final with values known at compile
time to avoid needless class loading. But be aware, you must recompile
B if the value of A.VERSION changes, or you will get the old value.

Another rule of thumb may be, instead of cross linking classes with
references to each others constants, refactor out the constants to a
third class, and reference it or extend it.

In a number of my projects I have a Config class where everything
constant (possibly computed) needed to configure a program for a
particular use are collected.
--
Roedy Green Canadian Mind Products
http://mindprod.com
It should not be considered an error when the user starts something
already started or stops something already stopped. This applies
to browsers, services, editors... It is inexcusable to
punish the user by requiring some elaborate sequence to atone,
e.g. open the task editor, find and kill some processes.

 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      09-25-2011
On 9/24/2011 8:09 PM, Roedy Green wrote:
> On Fri, 23 Sep 2011 17:40:20 -0700, Roedy Green
> <(E-Mail Removed)> wrote, quoted or indirectly quoted
> someone who said :
>
>> class A
>> {
>> static String VERSION = "1.0b";
>> }
>>
>> and
>> class B
>> {
>> static String VERSION = A.VERSION;
>> }

>
> restating, if the expression for A.VERSION cannot be evaluated an
> compile time, even final won't rescue you from having to include both
> A in your jar and indirectly loading A when you load B.


You keep harping on whether A is or is not present in "B's
jar." That depends on the jar packer, not on A and B.

Put it this way: Do you think java.lang.String appears in
"B's jar?"

--
Eric Sosman
http://www.velocityreviews.com/forums/(E-Mail Removed)d
 
Reply With Quote
 
markspace
Guest
Posts: n/a
 
      09-25-2011
On 9/24/2011 5:09 PM, Roedy Green wrote:
> Another rule of thumb may be, instead of cross linking classes with
> references to each others constants, refactor out the constants to a
> third class, and reference it



Generally, no. It's been tried, and found to not work well. A class
full of unrelated constants is just that: a class full of unrelated
constants. Put the constants where they belong. Use a decent build
system capable of figuring out what needs to be compiled.


> or extend it.



Dear god no. Known bad practice. Avoid!


 
Reply With Quote
 
Daniel Pitts
Guest
Posts: n/a
 
      09-25-2011
On 9/23/11 6:39 PM, Roedy Green wrote:
> On Fri, 23 Sep 2011 22:10:28 -0300, Arved Sandstrom
> <(E-Mail Removed)> wrote, quoted or indirectly quoted
> someone who said :
>
>> Which logical place is not in the code at all. Granted, I don't know
>> that Roedy's example is doing anything more than using "VERSION" as a
>> generic variable name (I hope).

>
> I chose it as an easy-to-understand example. In my example, VERSION
> is something you might display in a an About box.
>
> The question is really about accidentally dragging in some giant class
> when you had no intention of using its code.


If you are using a field from it, you *are* using its code.

Imagine the following scenario:

public class MyConstants {
public static final String VERSION;
public static final int ZERO;
static {
ZERO = 0;
VERSION = SomeOtherClass.calculateVersionNumber();
}
}

public class UsesOtherClass {
public static final VERSION = MyConstants.VERSION;
}

When UsesOtherClass is initialized, it requires MyConstants *and*
SomeOtherClass to be initialized.

In general, if you use some code, you are transiently using its
dependencies as well.

Although, I thought I read somewhere that constants can sometimes be
inlined (which can lead to other surprising behaviors if you recompile
only some of your classes on make).

 
Reply With Quote
 
Lew
Guest
Posts: n/a
 
      09-25-2011
On Sunday, September 25, 2011 11:25:49 AM UTC-7, Daniel Pitts wrote:
> Roedy Green wrote:
>> The question is really about accidentally dragging in some giant class
>> when you had no intention of using its code.

>
> If you are using a field from it, you *are* using its code.
>
> Imagine the following scenario:
>
> public class MyConstants {
> public static final String VERSION;
> public static final int ZERO;
> static {
> ZERO = 0;


Compile-time constant.

> VERSION = SomeOtherClass.calculateVersionNumber();


Not a compile-time constant.

They are treated differently.

> }
> }
>
> public class UsesOtherClass {
> public static final VERSION = MyConstants.VERSION;
> }
>
> When UsesOtherClass is initialized, it requires MyConstants *and*
> SomeOtherClass to be initialized.


But it compiles the compile-time constant in at compile time (hence the name, "compile-time" constant - amazing connection, eh?), so it doesn't need the source class at run time for that constant.

> In general, if you use some code, you are transiently using its
> dependencies as well.


The exception being compile-time constants.

> Although, I thought I read somewhere that constants can sometimes be
> inlined (which can lead to other surprising behaviors if you recompile
> only some of your classes on make).


More precisely, it's *compile-time* constants that get special treatment. People bandy about the term "constant" very carelessly.

Compile-time constants are bound in at compile time (the logic is compelling) as as literals. The surprising behaviors come at runtime from version mismatches and from the fact that transitive class dependencies are hidden by the compile-time constants having been bound at compile time.

--
Lew
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Making C better (by borrowing from C++) Masood C Programming 247 01-14-2008 05:42 AM
Borrowing a PC? Put Linux on it, via a USB drive Au79 Computer Support 0 08-01-2006 05:53 AM
Making C better (by borrowing from C++) masood.iqbal@lycos.com C Programming 86 02-28-2005 07:04 AM
TIME borrowing in synthesis whizkid VHDL 1 11-02-2004 03:39 PM
Borrowing someone else's XP disc - some questions Gary Glencross Computer Information 4 03-05-2004 03:48 AM



Advertisments