A truly uninstantiable class?

I

Ian Pilcher

Just wondering if it's really impossible to instantiate or extend the
following class:

package testing;

public abstract class BagOfStaticMethods
{
/** Prevent subclassing. */
private BagOfStaticMethods() {}
}

Thanks!
 
R

Ross Bamford

Just wondering if it's really impossible to instantiate or extend the
following class:

package testing;

public abstract class BagOfStaticMethods
{
/** Prevent subclassing. */
private BagOfStaticMethods() {}
}

Thanks!

Using normal techniques, you would be unable to instantiate or extend this
class from without as written. However, if your reason for going
'abstract' instead of 'final' is to allow an anonymous subclass to be
returned from a static method, then be warned that you will get a second,
package-private constructor if you do that.

Otherwise, 'final' with the private constructor would be a better bet I
think.
 
R

Roedy Green

Otherwise, 'final' with the private constructor would be a better bet I
think.

Constructors cannot be overridden even when you use the same name and
signature in a subclass. So in that sense all constructors are final
anyway..

All private methods are automatically final.
 
R

Roedy Green

package testing;

public abstract class BagOfStaticMethods
{
/** Prevent subclassing. */
private BagOfStaticMethods() {}
}

I'd think the private constructor should suffice. The use of abstract
gives off the false implication you are SUPPOSED to extend the class
to complete it.
 
O

Owen Jacobson

Constructors cannot be overridden even when you use the same name and
signature in a subclass. So in that sense all constructors are final
anyway..

All private methods are automatically final.

I believe he was referring to declaring the class 'final' (as opposed to
'abstract', as in the original post), not the constructor. Comme ça:

public final class Foo {
private Foo () {
assert false: "Uninstantiable?";
}
}
 
I

Ian Pilcher

Roedy said:
I'd think the private constructor should suffice. The use of abstract
gives off the false implication you are SUPPOSED to extend the class
to complete it.

Yeah. For some reason, I got obsessed with the fact that private
constructors can be invoked via reflection. Using an un-extendable
abstract class seemed like a way around this.

Reading the Javadoc for Constructor.newInstance, it looks like it just
throws an InstantiationException if it is invoked on a Constructor whose
underlying class is abstract. A final class with a private constructor
that throws an InstantiationException seems like a more straitforward
approach.
 
R

Ross Bamford

Constructors cannot be overridden even when you use the same name and
signature in a subclass. So in that sense all constructors are final
anyway..

All private methods are automatically final.

I pretty obviously meant final, instead of the OPs reference to abstract,
_on the class_ , and a private constructor.

And how on earth do you use the same name for a constructor on a subclass.
Tell me, because I want to know.
 
R

Roedy Green

And how on earth do you use the same name for a constructor on a subclass.
Tell me, because I want to know.

you refer to it as super in your subclass constructor. I was just
trying to point out that "final" constructors was not a useful
concept.
 
R

Ross Bamford

you refer to it as super in your subclass constructor. I was just
trying to point out that "final" constructors was not a useful
concept.

Well, granted, 'final' isn't a valid modifier for a constructor (which is
at least part of why I didn't suggest it ;)). But putting aside the whole
question of whether a constructor even has a name (apart from <init> if
you're picky), I think any reasonable person would look at any constructor
and, if asked it's 'name', give the name of the class upon which it is
declared. Wouldn't they?

In other words, I don't think someome looking at a class AnotherClass, a
subclass of SomeClass, would upon seeing a super() call inside the
constructor, think "Oh okay, so that constructor's called 'SomeClass'".

The specification for a constructor stipulates a 'SimpleTypeName' (i.e.
unqualified class name) between modifiers and parameters. I've always
thought of it more as the return type for an unnamed method, than a name
for an untyped method (not exactly right - constructors are void - but it
works as an abstraction).
 
S

Stefan Schulz

I believe he was referring to declaring the class 'final' (as opposed to
'abstract', as in the original post), not the constructor. Comme ça:

public final class Foo {
private Foo () {
assert false: "Uninstantiable?";
}
}

On an unrelated note, why does java.lang.Class offer a private constructor
that never throws any exception, but handles it specifically in
Constructor.setAccessible(boolean)? The constructor might just as well
throw the SecurityException when invocation is attempted.
 
R

Ross Bamford

On an unrelated note, why does java.lang.Class offer a private
constructor
that never throws any exception, but handles it specifically in
Constructor.setAccessible(boolean)? The constructor might just as well
throw the SecurityException when invocation is attempted.

I suppose it's to maintain the contract of setAccessible, i.e. that it
should throw SecurityException if the request is denied. I'd take that to
mean 'for whatever reason'.
 
S

Stefan Schulz

I suppose it's to maintain the contract of setAccessible, i.e. that it
should throw SecurityException if the request is denied. I'd take that to
mean 'for whatever reason'.

Makes sense. Not the design i would have chosen, but consistent with the
general reflection framework.
 
T

Thomas Hawtin

Owen said:
public final class Foo {
private Foo () {
assert false: "Uninstantiable?";
}
}

Odd use of asserts. Doesn't work if asserts are disabled. I've taken to
writing it as:

public abstract class Foo {
private Foo() {
throw new Error();
}
}

I suppose if I was more paranoid, I could declare the constructor to
throw Throwable. If only classes could be declared final abstract.

Tom Hawtin
 
T

Timbo

Thomas said:
Odd use of asserts. Doesn't work if asserts are disabled.

I think that is exactly the type of place to use assertions -- a
place where it should never evaluate to false. Anyway, I've never
seen a use of assert that does work if asserts are disabled :)
 
C

Chris Uppal

Thomas said:
I've taken to writing it as:

Odd choice of words; it sounds as if this is something you regularly, or at
least not infrequently, have a need for. Is that the case, and if so what
kinds of situations give rise to such a need ?

-- chris
 
P

P.Hill

Ross said:
In other words, I don't think someome looking at a class AnotherClass,
a subclass of SomeClass, would upon seeing a super() call inside the
constructor, think "Oh okay, so that constructor's called 'SomeClass'".

In the source code that is exactly what it is called AKA SomeClass,
but yes in the compile class file it doesn't have that name, so
I'm not sure what point you are trying to make.

-Paul
 
R

Ross Bamford

In the source code that is exactly what it is called AKA SomeClass,
but yes in the compile class file it doesn't have that name, so
I'm not sure what point you are trying to make.

-Paul

It was a nitpick really, but I was saying that given:

class SomeClass { /* ... */ }

class AnotherClass extends SomeClass {
public AnotherClass() {

}

public AnotherClass(boolean dummy) {
super();
}
}

If you were asked, informally, for the 'names*' of the two constructors in
AnotherClass, you would be more likely to say "AnotherClass for both" than
"AnotherClass and SomeClass".

This in response to the suggestion that one might declare a constructor
with the same 'name' as the superclass constructor by calling super(...)
from within it.

(The way I read the language spec, constructors don't have names per-se,
other than the 'SimpleTypeName' of the class upon which they're declared,
hence the 'informally' qualification above :) ).
 
T

Thomas Hawtin

Roedy said:
or better still the clearer:
UnsupportedOperationException

I want an Error not a RuntimeException. It would be a bug internal to
the class. UnsupportedOperationException is used when a subtype does not
support all the operations of its supertypes, which is not the case
here. And I don't want and fool's catch RuntimeException catching it.

Do constructors count as operations?

Tom Hawtin
 
R

Ross Bamford

I want an Error not a RuntimeException. It would be a bug internal to
the class. UnsupportedOperationException is used when a subtype does not
support all the operations of its supertypes, which is not the case
here. And I don't want and fool's catch RuntimeException catching it.

I'm not sure an Error is suitable here - this is a deliberate illegal
access rather than an incompatible runtime class change. Personally I
would use InstantiationException - although not a runtime exception, since
anyone invoking the constructor would be doing so reflectively I don't
think that'd matter too much. I think this case is within the spirit, if
not necessarily the letter, of that exception's spec which says:

"Thrown when an application tries to create an instance of a class using
the newInstance method in class Class, but the specified class object
cannot be instantiated because it is an interface or is an abstract class."

(from 1.5 Javadoc)

In other words, it would make the newInstance method behave as if it was
an abstract or interface class.

You might also consider InstantiationError, but that loses the benefit of
the above and is only thrown, according to it's doc, in case of
incompatible runtime class change.

Does it matter if the exception is caught? What about a bigger fool
catching Throwable?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top