Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / December 2007

Tip: Looking for answers? Try searching our database.

abstract vs. final

Thread view: 
Todd - 06 Dec 2007 14:06 GMT
Hello,

My buddy and I were talking about whether it is better to use abstract
or final on a class with the following "attributes":

1.  The class only contains static methods - hence there is no reason
for instantiating an object.
2.  The class will not be extended.

These statements are known to be true.

He feels that the class should be abstract due to the first
attribute.  I say final due to the second attribute (maybe with a
protected empty constructor).  Is there a middle ground that is
appropriate or is one more correct than the other?

This isn't a bet or anything, we are both trying to increase our
understanding of Java, object-oriented programming, and proper
programming techniques.

Thanks,
Todd
Lew - 06 Dec 2007 14:21 GMT
> Hello,
>
[quoted text clipped - 11 lines]
> protected empty constructor).  Is there a middle ground that is
> appropriate or is one more correct than the other?

I suspect that there are many correct answers, but I'd speak against
"abstract".  The purpose of "abstract" is not to prevent instantiation, the
purpose of "abstract" is to require that the class be extended, which is not
the purpose here.

A private (NOT protected!  that is useless to prevent class extension)
constructor, possibly with a 'final' class decoration, is the canonical
approach.  Josh Bloch talks about the idiom in /Effective Java/, IIRC.

Signature

Lew

lord.zoltar@gmail.com - 06 Dec 2007 14:50 GMT
> Hello,
>
[quoted text clipped - 18 lines]
> Thanks,
> Todd

Abstract is like an interface that can contain some implementation.
It's useful when the subclasses will be known to have some common
implementation methods. In this case an abstract class can contain
common implementation, where an interface would require that each
subclass duplicate the common implementation.

In my opinion (and I'm sure others will feel differently), final is
for classes such as Math, where it is VERY certain that there won't be
any extensions or implementations. I have never run into a situation
where I have a class that can be instantiated, but I NEVER want to
extend it. I've had the opposite though: classes that WERE final but
had to be modified to be non-final. The alternative to that would have
been a lot of copy-and-paste. ;)
But maybe one day I WILL want to make a class final... ;)
Lew - 06 Dec 2007 15:09 GMT
> Abstract is like an interface that can contain some implementation.
> It's useful when the subclasses will be known to have some common
> implementation methods. In this case an abstract class can contain
> common implementation, where an interface would require that each
> subclass duplicate the common implementation.

There may be no implementation or complete implementation in the abstract
class.  The point of declaring it "abstract" is to require that it be extended.

> In my opinion (and I'm sure others will feel differently), final is
> for classes such as Math, where it is VERY certain that there won't be
[quoted text clipped - 4 lines]
> been a lot of copy-and-paste. ;)
> But maybe one day I WILL want to make a class final... ;)

Given the dangers of class heritability, and the fact that composition most of
the time works better, the preference should be to declare most classes final
unless you've specifically designed them for heritability.

Josh Bloch explains many facets of this in /Effective Java/.

In practice this is an issue for APIs, that is, classes written for
third-party use.  Classes that aren't exposed for use by other projects
needn't be quite so rigorous in this matter.

Signature

Lew

Lasse Reichstein Nielsen - 06 Dec 2007 20:55 GMT
...
> 1.  The class only contains static methods - hence there is no reason
> for instantiating an object.
> 2.  The class will not be extended.
...
> He feels that the class should be abstract due to the first
> attribute.  I say final due to the second attribute (maybe with a
> protected empty constructor).  Is there a middle ground that is
> appropriate or is one more correct than the other?

It's not really a class. It's a namespace, that happens to be
implemented using a class declaration.

The "no instantiation" part should be enforced using a private
constructor (documenting that that is its sole purpose).
A private constructor (and no other constructors) also suffices
to prevent anybody from extending the class.

I'd add "final" just to make it clear that it can't be extended,
so you wouldn't have to deduce it from the missing constructor.

I wouldn't add "abstract", as that suggests that it should be
extended.

/L
Signature

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

Zig - 07 Dec 2007 06:28 GMT
> Hello,
>
[quoted text clipped - 6 lines]
>
> These statements are known to be true.

I would subject first off: The documentation should be the first place one  
goes to figure out how to use a class. If you document the intended use  
case ("this class is not intended to be instantiated"), then you've clear  
from users making expectations.

> He feels that the class should be abstract due to the first
> attribute.  I say final due to the second attribute (maybe with a
> protected empty constructor).  Is there a middle ground that is
> appropriate or is one more correct than the other?

A good IDE will probably issue an excessive/unused code warning for  
writing a constructor that never gets called. Of course, you can always  
add a @SupressWarnings, or just turn off that warning.

Does the object "work" if you instantiate it? Since presumably the result  
of "new MyObject()" is not much different from "new Object()", then the  
object "works" (meaning, to your knowledge, your instance methods won't  
throw Errors).

You should also ask yourself: how will these rules change in the next  
major revision of this class? What sort of support would that update need  
to offer your current version? If you might need to expose your class as  
subclassable for internal implementations in the future, then it's  
probably a good idea to mark the class final until that time.

From the other side of the table: In general, it is considered bad  
practice to call a static method like you would an instance method  
(myObject.staticMethod). Fortunately, when JUnit was designed (to pick one  
example), this principle wasn't followed to the letter, allowing the test  
developer to write

public void testMyMethod() throws Throwable {
    assertEquals(55, MyClass.myMethod(5));
}

rather than the more verbose:

public void testMyMethod() throws Throwable {
    Assert.assertEquals(55, MyClass.myMethod(5));
}

You might even want to go hogwild:

public void testMyMethod() throws Throwable {
    MyClass MC=new MyClass();    //non-production constructor; alias for code  
clarity only

    assertEquals(55, MC.myMethod(5));
}

This is of course a mute point with the "import static" mechanism in Java  
1.5, which is the preferred way to reference statics without the class  
prefix. Rather, consider this a scenario that should qualify as an  
exception from the general rule: being verbose is redundant, and henders  
the readability of the test's parameters and expected results.

Likewise, another developer could come across a routine using  
reflection/interrogation in a "bean-esk" way to do something useful:

public void remotelyCallFooMethods(Object o) throws Exception {
    for (Method m : o.getClass().getMethods())
        {
        if (m.getName().startsWith("foo"))
            executeOnRemoteHost(m, o);
        }
}
/**
* calls m.invoke(o), but on a remotely attached VM. Supports both instance  
& static methods
*/
public Object executeOnRemoteHost(Method m, Object o)

Probably not useful for your type of static methods, but as this is a  
theoretical case, somebody might run into it.

So, with those points presented, I stick with declaring classes like these  
"abstract". Other programmers still get to use "import static", for  
convenience. If the other fellow has a *really* compelling reason that I  
did not envision to instantiate this object, then it is only a  
inconvenience:

MyClass o=new MyClass() { };

And hopefully they scratched their head, revisited the docs, and were  
still convinced that there was a good reason to make an exception to a  
general rule.

> This isn't a bet or anything, we are both trying to increase our
> understanding of Java, object-oriented programming, and proper
> programming techniques.

For technique, I would stick to the principle that writing additional code  
for the express purpose of reducing functionality and/or limiting code  
reusability is wastefull. Error checking is great, just don't go out of  
your way to wall yourself off from unconsidered usecases with brick &  
mortar.

HTH,

-Zig
Lew - 07 Dec 2007 14:59 GMT
> A good IDE will probably issue an excessive/unused code warning for
> writing a constructor that never gets called.

It would have to be psychic, seeing the future and all.  How in the heck could
an IDE tell if a constructor never gets called?

"Because it's private and the class itself doesn't use it," you say?  Pfft.
There's no problem with such an idiom.  How is it even remotely something that
should be marked?

Since private constructors are a legitimate, legal and commonly-used idiom,
any IDE that flags such a use as "bad" or questionable should be thrown on the
pyre and its developers sent nasty messages.  Or the converse.

Signature

Lew

Chris Dollin - 07 Dec 2007 15:47 GMT
>> A good IDE will probably issue an excessive/unused code warning for
>> writing a constructor that never gets called.
>
> It would have to be psychic, seeing the future and all.  How in the heck could
> an IDE tell if a constructor never gets called?

By looking at the entire codebase.

If a constructor never gets used, it's pointless. If it were pointful, then
there would be a test for it, so it would be in the codebase, so no warning
would be issued.

Signature

Chris "Jack, bounding" Dollin

Hewlett-Packard Limited     Cain Road, Bracknell,                registered no:
registered office:          Berks RG12 1HN                       690597 England

Patricia Shanahan - 07 Dec 2007 17:24 GMT
...
> If a constructor never gets used, it's pointless....

On the contrary, an uncalled private constructor can be performing a
very useful task by preventing generation of a default constructor. This
is a very different situation from e.g. an unused local variable,
because removing the local variable declaration would not cause the
compiler to generate any additional, more accessible, variable declaration.

Blocking default constructor generation is a legitimate, documented
function of explicit constructor declarations. See the JLS,
http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.8.10,
"8.8.10 Preventing Instantiation of a Class".

Patricia
Lew - 08 Dec 2007 01:15 GMT
>>> A good IDE will probably issue an excessive/unused code warning for
>>> writing a constructor that never gets called.
[quoted text clipped - 6 lines]
> there would be a test for it, so it would be in the codebase, so no warning
> would be issued.

That is so bogus.  You make a constructor private specifically to prevent its
being used; that is not an error.

And you can't see the "entire codebase", because a Java codebase is
open-ended.  It can change or increase while the program is running.
Furthermore, you have no way of knowing how another program will use the class
- maybe some as-yet-undeveloped program will use the constructor, if it isn't
private.

Anyhow, a private constructor is never an error.

Signature

Lew

Chris Dollin - 10 Dec 2007 11:28 GMT
>>>> A good IDE will probably issue an excessive/unused code warning for
>>>> writing a constructor that never gets called.
[quoted text clipped - 9 lines]
> That is so bogus.  You make a constructor private specifically to prevent its
> being used; that is not an error.

OK, you got me on that one. I had forgotten that.

> And you can't see the "entire codebase", because a Java codebase is
> open-ended.  It can change or increase while the program is running.
> Furthermore, you have no way of knowing how another program will use the class
> - maybe some as-yet-undeveloped program will use the constructor, if it isn't
> private.

If the constructor is to have a point other than preventing the external
use of itself (a cunning trick and a standard idiom, that much I'll grant),
so that it's exposed to external use, then it should have a test -- and
hence a use will be in /the codebase the IDE can see/.

If it hasn't got a test, then surely something is already broken.

> Anyhow, a private constructor is never an error.

That depends on what you mean by "error"; does nobody make things private
(or constructors) by mistake, or do you not count mistakes as errors?

Signature

Chris "only a /small/ egg" Dollin

Hewlett-Packard Limited                                          registered no:
registered office: Cain Road, Bracknell, Berks RG12 1HN          690597 England

Lew - 10 Dec 2007 16:00 GMT
>> And you can't see the "entire codebase", because a Java codebase is
>> open-ended.  It can change or increase while the program is running.
[quoted text clipped - 4 lines]
> If the constructor is to have a point other than preventing the external
> use of itself (a cunning trick and a standard idiom, that much I'll grant),

and mentioned in the JLS!

> so that it's exposed to external use, then it should have a test -- and
> hence a use will be in /the codebase the IDE can see/.

What about if it has a point as an API?  Would it matter if none of the code
in the java.util package invoke ArrayList()?  Of course not, because that
constructor is specifically designed for public use by programs Sun not only
could never see, but never intended to see.

Test code being absent should not raise a compiler warning, should it?

Of /course/ there should be test code, but whether the IDE can see it is
irrelevant.  What if the test team was separate, and kept the code in a
separate project?  Should the IDE or compiler then issue an error or warning?

Of course not.

> If it hasn't got a test, then surely something is already broken.

Actually, not surely, and that is the problem.  In any event, at this point
you are arguing that there should be an error for a lack of test code, which
really is not the compiler's responsibility.

>> Anyhow, a private constructor is never an error.
>
> That depends on what you mean by "error"; does nobody make things private
> (or constructors) by mistake, or do you not count mistakes as errors?

I meant it's never a compiler error.  Don't go switching contexts on me, now.

Is the compiler now supposed to tell you that you made a mistake?

It will, of course, if /another/ class tries to use that private constructor,
but that's not what you suggested.  How is a compiler supposed to know, when
compiling the class with a private constructor, that the programmer made a
mistake, hm?

So let's drop the straw man argument and stick with the context you
introduced, that of a compiler error.

Signature

Lew

Chris Dollin - 11 Dec 2007 09:20 GMT
>>> And you can't see the "entire codebase", because a Java codebase is
>>> open-ended.  It can change or increase while the program is running.
[quoted text clipped - 11 lines]
>
> What about if it has a point as an API?

Then it should have a test.

> Would it matter if none of the code  
> in the java.util package invoke ArrayList()?  Of course not, because that
> constructor is specifically designed for public use by programs Sun not only
> could never see, but never intended to see.
>
> Test code being absent should not raise a compiler warning, should it?

If it's a happy consequence of "no use seen for this non-private thingy",
then I'm glad if it does.

Here's what I think I'm talking about. We have some source code which
we're developing. There's a thingy -- in the original example, a constructor,
but it can be a plain method or a field or whatever -- which is never
used in the visible source codebase. Can/should the IDE (or a non-IDE compiler)
reasonably warn that there's no use of that thingy?

You had written:

|> Zig wrote:
|>> A good IDE will probably issue an excessive/unused code warning for
|>> writing a constructor that never gets called.
|>
|> It would have to be psychic, seeing the future and all.  How in the heck could
|> an IDE tell if a constructor never gets called?

So I said:

| By looking at the entire codebase.

That's the entire available /source/ codebase that we're working on; I
don't need a psychic compiler for that.

> Of /course/ there should be test code, but whether the IDE can see it is
> irrelevant.  What if the test team was separate, and kept the code in a
> separate project?

It is my position that the developer of the code should be writing unit
tests for it in test-first style, right there and then, independently of
whatever other code other test teams might write, because I'm a TDD
advocate.

So if the IDE can't see a test for that exposed thingy, it's because
no test has been written. A compiler/IDE being able to spot that,
whether by some specialised test-not-present logic or by a happy
accident of no-use-anywhere, is, in my view a Very Good Thing.

> > Should the IDE or compiler then issue an error or warning?  
>
> Of course not.

As you will see, my answer is "of course".

Our different positions on testing will lead to different answers. Naturally
I shall think my answer is better than yours, but I hope I've explained the
rationale of mine.

>> If it hasn't got a test, then surely something is already broken.
>
> Actually, not surely, and that is the problem.  In any event, at this point
> you are arguing that there should be an error for a lack of test code, which
> really is not the compiler's responsibility.

Whether or not it's the compiler's responsibility -- I note that over the years
what counts as the responsibility of the compiler [or IDE] seems to have
increased as we get better at automating inspections for iffy code -- it
happens that /if/ the compiler/IDE spots that there are no uses in the
visible codebase of a non-private thingy /and/ each non-private thingy in
the source is expected to have a test [as I think is good practice] /then/
the compiler/IDE will spot missing tests without needing special-case code.

I think this is a Good Thing.

>>> Anyhow, a private constructor is never an error.
>>
>> That depends on what you mean by "error"; does nobody make things private
>> (or constructors) by mistake, or do you not count mistakes as errors?
>
> I meant it's never a compiler error.  Don't go switching contexts on me, now.

I'm not switching contexts: it was a request for clarification, since the
binding for "error" wasn't clear to me.

Signature

Chris "attempting exposure" Dollin

Hewlett-Packard Limited registered office:                Cain Road, Bracknell,
registered no: 690597 England                                    Berks RG12 1HN

Lew - 11 Dec 2007 14:16 GMT
It is not the compiler's responsibility to find test code; it's the compiler's
responsibility to check the compilability of the artifact itself.

Your idea that there should be a tool, perhaps as part of JUnit or similar
framework, to check for test coverage is a good one.

You could use the presence of such a tool as an evaluative factor in choosing
an IDE.

But it is no part of what the compiler should do.

Signature

Lew

Chris Dollin - 12 Dec 2007 08:41 GMT
> It is not the compiler's responsibility to find test code; it's the compiler's
> responsibility to check the compilability of the artifact itself.
>
> Your idea that there should be a tool, perhaps as part of JUnit or similar
> framework, to check for test coverage is a good one.

(Isn't "test coverage" a stronger notion that just "every entity has a test",
more like "every /code path/ has a test"?)

> You could use the presence of such a tool as an evaluative factor in choosing
> an IDE.
>
> But it is no part of what the compiler should do.

Clearly we have different opinions on what compilers "should", or
perhaps "should not" do. I think it's clearly /useful/ for a compiler
to [be able to] note that there's no use made of some declared entity [1]
in some codebase and I would not apply a "should not" to remove a
useful feature. (Usual tradeoff remarks apply.)

I think I'm done.

[1] I spelled `entity` "thingy" in earlier posts, for want of remembering
   the word; I'm not trying to change what I meant.

Signature

Chris "and you've got to be ready" Dollin

Hewlett-Packard Limited     Cain Road, Bracknell,                registered no:
registered office:          Berks RG12 1HN                       690597 England

Lew - 12 Dec 2007 15:29 GMT
>> It is not the compiler's responsibility to find test code; it's the compiler's
>> responsibility to check the compilability of the artifact itself.
[quoted text clipped - 4 lines]
> (Isn't "test coverage" a stronger notion that just "every entity has a test",
>  more like "every /code path/ has a test"?)

Doesn't affect the point I was making.

>> You could use the presence of such a tool as an evaluative factor in choosing
>> an IDE.
>>
>> But it is no part of what the compiler should do.
>
> Clearly we have different opinions on what compilers "should", or

The word is "compiler".  Its job is to compile, not to test.  Only things that
break the language rules should be flagged.  Not using a constructor doesn't
break the language rules.  Note that the test suite will not be in the
production environment, so even though you have test code in the IDE, it won't
be there in the release.  So those constructors will still wind up "unused"
even if your fantasy compiler had vetted them.

> perhaps "should not" do. I think it's clearly /useful/ for a compiler
> to [be able to] note that there's no use made of some declared entity [1]

Useful to you, but a true annoyance to everyone else.

> in some codebase and I would not apply a "should not" to remove a
> useful feature. (Usual tradeoff remarks apply.)

I would apply a "should not" to a feature that is not actually useful, as
having a compiler perform the function of a test tool would not be.

Signature

Lew

Chris Dollin - 12 Dec 2007 15:51 GMT
>> Clearly we have different opinions on what compilers "should", or
>
> The word is "compiler".  Its job is to compile, not to test.  Only things that
> break the language rules should be flagged.

Which part of "Clearly we have different opinions" was opaque to you?

Your attitude to what the compiler (are we distinguishing "compiler" and "IDE"
here?) 'should' do sound /just like/ early attitudes to what C compilers should
or should not do -- the minimum required to generate code and report violations
of what the language said was OK. Other fancy checking was left to lint. As
far as I can tell, nowadays C compilers are /expected/ to spot likely
problems and -- configurably -- report them, because that's more effective
for developers, rather than being compatible with a purist attitude to the
names of things. (Not that lint is obsolete, of course.)

I don't see why Java should be different in this respect. (Note that I'm not
/demanding/ that compilers should report unused entities. Did you think I was?)

>> perhaps "should not" do. I think it's clearly /useful/ for a compiler
>> to [be able to] note that there's no use made of some declared entity [1]
>
> Useful to you, but a true annoyance to everyone else.

Oh, /please/. I refer you to Zig's earlier post, which started this
subdiscussion:

| A good IDE will probably issue an excessive/unused code warning for  
| writing a constructor that never gets called. Of course, you can always  
| add a @SupressWarnings, or just turn off that warning.

I read that as at least one other poster not counting it as a "true
annoyance". Your "everyone else" is presently just handwaving, and
your assumption that such a feature would be unswitchoffable surprising
given the previous discussion.

I thought I was done, but I was wrong. This time I /am/ done.

Signature

Chris "silence is transmission failure" Dollin

Hewlett-Packard Limited     Cain Road, Bracknell,                registered no:
registered office:          Berks RG12 1HN                       690597 England

Lew - 12 Dec 2007 16:21 GMT
>>> Clearly we have different opinions on what compilers "should", or
>> The word is "compiler".  Its job is to compile, not to test.  Only things that
>> break the language rules should be flagged.
>
> Which part of "Clearly we have different opinions" was opaque to you?

No part.

> Your attitude to what the compiler (are we distinguishing "compiler" and "IDE"

Yes, we most certainly are.

> here?) 'should' do sound /just like/ early attitudes to what C compilers should
> or should not do -- the minimum required to generate code and report violations
[quoted text clipped - 3 lines]
> for developers, rather than being compatible with a purist attitude to the
> names of things. (Not that lint is obsolete, of course.)

Do C compilers these days report when library features are not used?  I was
not aware of that.

> I don't see why Java should be different in this respect. (Note that I'm not
> /demanding/ that compilers should report unused entities. Did you think I was?)

Yes, I did.

>>> perhaps "should not" do. I think it's clearly /useful/ for a compiler
>>> to [be able to] note that there's no use made of some declared entity [1]
[quoted text clipped - 6 lines]
> | writing a constructor that never gets called. Of course, you can always  
> | add a @SupressWarnings, or just turn off that warning.

Good IDE, yes, compiler, no.  Compilers traditionally have not taken on the
role of test tools.

> I read that as at least one other poster not counting it as a "true
> annoyance". Your "everyone else" is presently just handwaving, and

Not applicable.  The quoted remark was about an IDE, not a compiler.

> your assumption that such a feature would be unswitchoffable surprising
> given the previous discussion.

I favor having this in an IDE.  It's the compiler that I aver should not.

> I thought I was done, but I was wrong. This time I /am/ done.

Thank you for the enlivening discussion.

Signature

Lew

Roedy Green - 09 Dec 2007 12:52 GMT
On Thu, 6 Dec 2007 06:06:42 -0800 (PST), Todd
<todd.heidenthal@lmco.com> wrote, quoted or indirectly quoted someone
who said :

>He feels that the class should be abstract due to the first
>attribute.  I say final due to the second attribute (maybe with a
>protected empty constructor).  Is there a middle ground that is
>appropriate or is one more correct than the other?

abstract to me implies you are SUPPOSED to extend the class before
you.

final means it would not make sense to extend the class.  IntelliJ
Idea encourages the use of final to mean "there is no class that
extends this one, for now".

Neither condition is satisfied. So I would leave both attributes out.

I would however give it a dummy private constructor as an indicator it
is not for instantiation.

final gives you no speed improvement for static methods.  They are in
a sense already final.
Signature

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Lew - 09 Dec 2007 17:00 GMT
> final means it would not make sense to extend the class.  IntelliJ
> Idea encourages the use of final to mean "there is no class that
> extends this one, for now".

"Nor can there ever be."

<http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.1.1.2>
> A compile-time error occurs if the name of a final class appears
> in the extends clause (§8.1.4) of another class declaration;
> this implies that a final class cannot have any subclasses.
> A compile-time error occurs if a class is declared both final
> and abstract, because the implementation of such a class could
> never be completed (§8.1.1.1).

Signature

Lew

Roedy Green - 10 Dec 2007 11:51 GMT
>> final means it would not make sense to extend the class.  IntelliJ
>> Idea encourages the use of final to mean "there is no class that
>> extends this one, for now".
>
>"Nor can there ever be."

IntelliJ and Sun have different philosophies.  The code refactor
encourages you to mark final any class that has no subclasses for now.
Signature

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Lew - 10 Dec 2007 16:02 GMT
>>> final means it would not make sense to extend the class.  IntelliJ
>>> Idea encourages the use of final to mean "there is no class that
[quoted text clipped - 3 lines]
> IntelliJ and Sun have different philosophies.  The code refactor
> encourages you to mark final any class that has no subclasses for now.

Philosophies?  What does that have to do with it?  The JLS *mandates* what
final means; IntelliJ is not at liberty to change the language.

Signature

Lew

Lew - 10 Dec 2007 16:18 GMT
>>>> final means it would not make sense to extend the class.  IntelliJ
>>>> Idea encourages the use of final to mean "there is no class that
[quoted text clipped - 6 lines]
> Philosophies?  What does that have to do with it?  The JLS *mandates*
> what final means; IntelliJ is not at liberty to change the language.

Wait, I just got where you said "the code refactor encourages" - you mean to
say, that later one *removes* the final decoration if one decides to make the
class heritable, right?

With that I agree wholeheartedly.  I don't need IntelliJ to tell me that.  It
does make sense, and is validated in /Effective Java/ by Joshua Bloch, that a
class should be non-heritable by default in the programmer's mind.

Signature

Lew

Daniel Pitts - 10 Dec 2007 17:26 GMT
>>>>> final means it would not make sense to extend the class.  IntelliJ
>>>>> Idea encourages the use of final to mean "there is no class that
[quoted text clipped - 15 lines]
> Joshua Bloch, that a class should be non-heritable by default in the
> programmer's mind.

In C++, all variables/references should be const by default. In Java,
all references/primitives should be final by default.  And if Java had
support to make an instance immutable, that should be enabled by default :-)

Its unfortunate that the "best practice" case is the more verbose. Many
people would prefer to have a keyword such as "modifiable" or
"extendable" rather than the converse.

Signature

Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>

Roedy Green - 13 Dec 2007 22:10 GMT
On Mon, 10 Dec 2007 09:26:33 -0800, Daniel Pitts
<newsgroup.spamfilter@virtualinfinity.net> wrote, quoted or indirectly
quoted someone who said :

>Its unfortunate that the "best practice" case is the more verbose. Many
>people would prefer to have a keyword such as "modifiable" or
>"extendable" rather than the converse.

I agree. the keyword could be something like var, mutable, changes,
alter, fickle, unstable.

Perhaps in the successor to Java.

Or perhaps if someone ever writes a SCID, ordinary java could display
"missing final" as "var", or with a special twitching icon or colour.

To traditional users viewing your code, they would see it as it is
now.

see http://mindprod.com/jgloss/scid.html

Even an IDE might use colour to remind you of non-final status.

Signature

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Roedy Green - 13 Dec 2007 22:05 GMT
>Wait, I just got where you said "the code refactor encourages" - you mean to
>say, that later one *removes* the final decoration if one decides to make the
>class heritable, right?

If you have any classes without subclasses, the Inspector will report
as a "defect" that they are missing the "final".  If you want the Lint
perfect stamp, you need to mark all unsubclassed classes final.

I think this is a perfectly valid thing to do for in-house use.
Subclassing a class for the first time is sort of like taking its
virginity. It should not be done lightly.  You could be made aware, to
make you double check you are subclassing the correct class.

For public distribution, without source, you need to be more sparing
with final so you don't screw up your clients.  If you distribute
source, they can fairly easily peel off the final.

I go along with the inspector mainly for documentation purposes.  I
like the assurance of the "final" there are no subclasses I could muck
up by changing a class.
Signature

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Roedy Green - 13 Dec 2007 21:59 GMT
>Philosophies?  What does that have to do with it?  The JLS *mandates* what
>final means; IntelliJ is not at liberty to change the language.

Fine. But they DID.
Signature

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Lew - 14 Dec 2007 01:51 GMT
>> Philosophies?  What does that have to do with it?  The JLS *mandates* what
>> final means; IntelliJ is not at liberty to change the language.
>
> Fine. But they DID.

Eclipse has an inspector that hints at the lack of "final" in class
declarations, but it manages to do it without violating the language spec.

Are you certain IntelliJ actually changes the Java language?  I was under the
impression from what you said that it encourages making a class final at
first, and /removing/ the 'final' later if you change your mind.  Did I
misunderstand you?

Signature

Lew

Daniel Dyer - 14 Dec 2007 02:20 GMT
>>> Philosophies?  What does that have to do with it?  The JLS *mandates*  
>>> what final means; IntelliJ is not at liberty to change the language.
[quoted text clipped - 8 lines]
> class final at first, and /removing/ the 'final' later if you change  
> your mind.  Did I misunderstand you?

I guess Roedy is referring to the "Declaration can have final modifier"  
inspection.

"This inspection reports all fields, methods or classes, found in the  
specified inspection scope, that may have a final modifier added to their  
declarations.  Use check boxes in the inspection options below, to define  
which declarations are to be reported."

You can enable it for classes, methods and/or fields.  Mine is only set to  
report fields (I think this is the default, or maybe the inspection is  
disabled by default).  By default this inspection generates warnings but  
all warnings can be upgraded to errors if you so choose.

There is also a "final class" inspection which does the exact opposite, so  
you wouldn't want both inspections enabled at the same time:

"This inspection reports any instances of classes being declared final.  
Some coding standards discourage final classes."

Dan.

Signature

Daniel Dyer
http://www.uncommons.org

Lew - 14 Dec 2007 03:10 GMT
> I guess Roedy is referring to the "Declaration can have final modifier"
> inspection.
[quoted text clipped - 14 lines]
> "This inspection reports any instances of classes being declared final.
> Some coding standards discourage final classes."

This seems similar to Eclipse's way.  So they DIDN'T redefine the language.

Signature

Lew

Roedy Green - 14 Dec 2007 16:00 GMT
> So they DIDN'T redefine the language.

Nope. They did not redefine the language, unless you consider that bit
of the JLS on the philosophy of using final part of the language. That
bit of philosophy is not relevant to how a given string of text
compiles.  It is a suggestion as to how final should be used in good
coding practice.

Signature

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Lew - 15 Dec 2007 01:40 GMT
>> So they DIDN'T redefine the language.
>
[quoted text clipped - 3 lines]
> compiles.  It is a suggestion as to how final should be used in good
> coding practice.

You're clearly not referring to the part of the JLS that says,
> A compile-time error occurs if the name of a final class
> appears in the extends clause (§8.1.4) of another class declaration;
> this implies that a final class cannot have any subclasses.
<http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.1.1.2>

To what in the JLS are you referring?

Signature

Lew

Roedy Green - 14 Dec 2007 15:57 GMT
>Are you certain IntelliJ actually changes the Java language?

No. It simply suggests you insert final on every class without
subclasses every time you run the inspector.  I am in the habit of
liking lints to say all is fine.  It is like wanting to remove all
warning messages from your Java code.

If you ignore those requests, you have to study the list of
suggestions carefully to make sure there are no other flavours in
there.

I think somewhere way back you misinterpreted what I was saying and I
have not been able to shake you of that interpretation even through
several tries.

What I am saying is the philosophy of the authors of the Inspector is
that you should apply "final" to any classes without subclasses, and
if you later decide you need to subclass, you should manually remove
the final keyword. "final" block subclassing in the perfectly usual
way.

The difference is in Sun philosophy, "final" means not subclassable,
and WILL NEVER be subclassable.  Intellij philosophy is, not
subclassed, not subclassable, but might be some day, if someone
removes the "final".

From the compiler's point of view, the two philosophies are not
distinguishable. They refer to future intent of humans, nothing to do
with how the code operates now.

As you quoted, Sun makes its philosophy explicit in the JLS, though of
course there in nothing to stop you from changing your mind and
removing the "final".
Signature

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Lew - 15 Dec 2007 01:42 GMT
>> Are you certain IntelliJ actually changes the Java language?
>
[quoted text clipped - 10 lines]
> have not been able to shake you of that interpretation even through
> several tries.

Surely you're not ignoring where I said,
> Wait, I just got where you said "the code refactor encourages" -
> you mean to say, that later one *removes* the final decoration
[quoted text clipped - 3 lines]
> It does make sense, and is validated in /Effective Java/ by Joshua Bloch,
> that a class should be non-heritable by default in the programmer's mind.
?

Signature

Lew

Lew - 15 Dec 2007 01:47 GMT
>>> Are you certain IntelliJ actually changes the Java language?
>>
[quoted text clipped - 21 lines]
>> programmer's mind.
> ?

Or where I asked:
> I was under the impression from what you said that it encourages
> making a class final at first, and /removing/ the 'final' later
> if you change your mind.  Did I misunderstand you?
?

Signature

Lew



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.