Public constructor of a private class [duplicate] - java

This question already has answers here:
Should we declare a public constructor when the class is declared as package private?
(2 answers)
Closed 8 years ago.
I am new to Java. I want to know what it is the use of public constructor in a private class. Private class inside the class can be initialized from the same class then what it is the use to make the constructor of private class to public?
public class MainActivity extends Activity {
private class AcceptThread extends Thread {
public AcceptThread() {
}
}
}

There doesn't seems to be any real use case for public or protected modifiers with private classes. If you have multiple classes in a single file though (but not nested or local), you need non-private constructors to instantiate the private classes.
// X.java
public class X {
private Y y = new Y();
}
class Y {
Y () {
// if this were private, X wouldn't be able to create an instance of Y
}
}
Actually default or protected visibility would be enough to create an instance in this case. All non-private modifiers allow you to create instances from other classes within the same package but practically have the same visibility.
The private class isn't visible to classes outside of the package, so public methods have no use here.
The private class can't be extended by classes outside of the package, so protected has no use either.
Even when using reflections, a public constructor is not accessible by default from other packages and will throw a IllegalAccessException. It checks the class visibility first, then the member visibility.
The default modifier is the most restrictive modifier that allows you to directly call the constructor from other classes, so package-private seems to be the most appropriate visibility for the constructor and also any other non-private methods. This also has the advantage that if you change the class visibility in the future, you don't accidentally expose the constructor or any methods to the public.

You know, I ask myself this question almost each time I make a private inner class, but I always assumed that there could be some (possibly contrived) reason for a public constructor. So #kapep 's answer got me tingling and encouraged to find ways to require a public constructor on a private inner class, but the more I think and experiment with it, the more I think the holes are plugged.
Possible angles, all of which failed me:
Serialisation: When unmarshalling an object whose superclass is not serializable, the superclass needs a no-arg constructor accessible from the subclass. So, protected should always suffice here.
Reflective tools: Code that uses reflection to get the inner class constructor through a returned instance. Fails because the type visibility is checked first, as #kapep pointed out, though it leaves a rather interesting error message:
Exception in thread "main" java.lang.IllegalAccessException: Class A can not access a member of class contrived.B$C with modifiers "public"
Inner class extension shenanigans: Don't try this at home:
package a;
class Outer {
private class Inner {
}
}
package b;
// compile error: Outer.Inner has private access in Outer
class Extender extends a.Outer.Inner {
Extender(a.Outer outer) {
outer.super();
}
}
Seemed promising at first, but I didn't get too far with that one.
In the end, I could not find a way to make a public constructor on a private inner class useful.
Then why is this technically legal despite having no use? Probably because the compiler automagically inserts a no-arg public constructor when no other constructor is provided. Hence the language should not disallow this constructs. More of an artefact than a reason, though.

Related

Inheritance Java private members

i have been going through Inheritance in java. My question is if private members are not inherited how come they end up in memory. Is there something going on internally to resolve this issue or they are just hidden/un accesible wihout public member function of the parent class.
here is java doc
"A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass.
A nested class has access to all the private members of its enclosing class—both fields and methods. Therefore, a public or protected nested class inherited by a subclass has indirect access to all of the private members of the superclass."
They are in memory, but you don't have access to them.
Example:
class A
{
private int foo;
public int getFoo( ) { return foo; }
...
}
class B extends A
{
...
}
Every instance of class B does, in fact, contain an integer foo under the hood.
But, you cannot access it directly, because it is declared private. You can access it indirectly, via the getFoo method, because that one is public.
Your object has Class reference in it. Your object's Class had parent Class reference in it. That's why private methods are still in memory - they're referenced by parent class.
They are just inaccessible normally, you can access them with e.g. Method.setAccessible(). You can get Method's by reflection on parent Class.

private abstract classes in Java [duplicate]

This question already has answers here:
Why nested abstract class in java
(2 answers)
Closed 8 years ago.
I am a relative newcomer to Java. I recently came across a private static abstract class inside a regular class while browsing some Android app source code. What could be a use case for such a nested class? How would it be used and what sort of design benefits are there from using such a class?
I've never come across this pattern before myself, but I can imagine it being useful if:
You want to implement an interface in a similar way in a bunch of nested classes (e.g. to be returned from public methods within the enclosing class)
Those interface implementations have a lot of code in common (hence the abstract class)
You don't need any code other than the implementations to know about the abstract class
The subclasses of the abstract class may well be private as well. (Typically when I write nested classes, they're private implementation details.) For example:
public interface Foo {
// Methods here
}
public class FooFactory {
public static Foo getFoo1() {
return new Foo1();
}
public static Foo getFoo2() {
return new Foo2();
}
private static abstract class AbstractFoo implements Foo {
// Implement methods in Foo in terms of
// doSomething()...
// Implementation-specific method
public abstract void doSomething();
}
private static class Foo1 extends AbstractFoo {
public void doSomething() {
}
}
private static class Foo2 extends AbstractFoo {
public void doSomething() {
}
}
}
What could be a use case for such a nested class?
You would use this if:
you were going to implement a number of nested classes with common functionality, and
you didn't want the base class with that functionality to be visible.
You would probably also make the leaf classes either final or private.
How would it be used and what sort of design benefits are there from using such a class?
See above. Basically, you are hiding the class so that it cannot be directly subclassed outside of the outermost enclosing class. I think this will also prevent the subclasses from being used polymorphically outside of the outermost enclosing class.
This is not a common use-case, but I imagine it is sensible in the context that you found it.
A typical use is to replace the equivalent of a C struct - for instance a small class that contains a name and a value and gets stored in a List or Map in the enclosing class. Because it is not used outside of the compilation unit, it can be private.
The static keyword usage is a bit odd here; all it means is that the class has no connection with the enclosing class.
Making it abstract is unusual - it indicates that there will be concrete implementations and I have never done that. YMMV...
The purpose of a nested class is to clearly group the nested class with its surrounding class, signaling that these two classes are to be used together.
Nested classes are considered members of their enclosing class. Thus, a nested class can be declared public, package (no access modifier), protected and private (see access modifiers for more info).
Static Nested Classes
Static nested classes are declared like this:
public class Outer {
public static class Nested {
}
}
In order to create an instance of Nested you must reference it by prefixing it with the Outer class name, like this:
Outer.Nested instance = new Outer.Nested();
A static nested class is essentially a normal class that has just been nested inside another class. It interacts with its enclosing class in the same way. Being static, a static nested class can only access instance variables of the enclosing class via a reference to an instance of the enclosing class.

Correct way of implementing class impossible to instantiate [duplicate]

This question already has an answer here:
Correct way to prevent instantiation in Java [closed]
(1 answer)
Closed 9 years ago.
Short:
Do I need to do something else but leaving out constructor?
Long:
I want to implement class which cannot be instantiate. I have find example in Math class here: http://docs.oracle.com/javase/6/docs/api/java/lang/Math.html
So I would write same thing:
public final class MyClass{
public static int doubleMe(int x){
return 2*x;
}
}
Constructor is absent, so instantiation should be impossible.
But I am not sure about making my class final. Maybe (not necessarily) I would like to extend it in the future (eg. public class myClassB extends myClass) and this keyword will prevent it - so does it have to be there?.
Do I need to do something else but leaving out constructor?
Yes. If you don't write a constructor yourself, Java will provide one.
You need to write your own private constructor:
public final class MyClass {
// Prevent the compiler from supplying a constructor automatically.
private MyClass() {}
public static int doubleMe(int x){
return 2*x;
}
}
(I've fixed the name of your class to follow normal Java naming conventions.)
If you look at the source code for java.lang.Math you'll find a private constructor there for the same reason.
But I am not sure about making my class final. Maybe (not necessarily) I would like to extend it in the future (eg. public class myClassB extends myClass) and this keyword will prevent it - so does it have to be there?.
You should only extend your class for reasons of polymorphism - which aren't relevant for a class which can't be instantiated.
Constructor is absent, so instantiation should be impossible.
No - if there is no constructor declared, then Java automatically gives the class an implicit default constructor, with no formal arguments and no throws clause (JLS §8.8.9). You need to explicitly declare a private constructor in order to make the class impossible to instantiate from the outside. Now as for your second concern: it makes no sense to extend a class that is impossible to instantiate, and hence it would make sense to declare your class as final - although this is not a requirement for making it un-instantiateable.
You might find the following section of the JLS relevant: §8.8.10: Preventing Instantiation of a Class.
In addition to making every method static, mark the class as abstract. This will prevent it from being instantiated.
abstract public class MyClass {
...
}
Creating a private constructor will prevent classes outside MyClass from constructing it, but won't stop one of the methods from within MyClass from doing it (private constructors are visible to the class itself).
Use abstract instead of final.
Use one (well, actually as many as you like) constructor and throw an unchecked exception from it.
Nobody will ever be able to create an instance of such a class.
Though, they can use static methods/fields of the class.
The approach sounds barbarian, but formally it will work.

Why can't you have a protected abstract class in Java?

I have an abstract class which looks like:
abstract class AbstractFoo implements Bar {
//Code goes here
}
However when I try to make AbstractFoo protected I get an error compile time error complaining that it is an illegal modifier.
protected abstract class AbstractFoo implements Bar {
//Code goes here
}
Why can't you have a protected abstract class within Java?
EDIT: I should probably mention that this is not vanilla Java and is actually Blackberry / J2ME.
As many others have noted, the restriction here has nothing to do with the fact that your class is abstract, but rather in the visibility modifier you have chosen to use. Keep in mind what each of these visibility modifiers means:
For the class in which you are using the keyword...
private: Only visible to this class
(default/package private): Only visible to this class and classes in its package
protected: Visible to this class, classes in its package, and subclasses of this class
public: Visible to any class
Top level classes cannot be declared private, because then nothing would ever be able to access them.
But your question stems around why they may not be declared protected. It is clear that a protected top-level class (were it able to exist) would be visible to itself (every class is visible to itself). It is also clear that a protected top-level class would be visible to classes in its package. However, making it visible to its subclasses is tricky. Which classes should be allowed to inherit our protected class?
If it is all of them, then our class might as well be public, because then we're saying that any class has the right to access our protected class. If it's none of them, then our class might as well be package-private, since only the other two conditions (being visible to itself and things in its package) are met. And it can't be "some of them," since we would need a way of defining which classes can access it, which is what the visibility modifier was for in the first place.
So for these reasons, top-level classes cannot be private or protected; they must be package-private or public.
Top level classes can only be public or package-private (default).
public class PublicClass {
protected class InnerClass { } //protected makes sense here
}
class PackagePrivateClass { }
Since: PublicClass and PackagePrivateClass are both top-level classes here they cannot have other access-modifiers, private and protected.
Only the public and the default access-modifiers are allowed for the top-level classes.
But for the inner member classes other modifiers are also allowed.
That abstract has nothing do here most probably.
You can; the following code compiles fine:
public class Main {
interface Bar {}
protected abstract class AbstractFoo implements Bar {}
public static void main(String[] args) {}
}
I do not believe the premise of the question. I successfully compiled the below code:
class prot
{
public abstract class pubab
{
}
protected abstract class protab
{
}
abstract class packprivab
{
}
private abstract class privab
{
}
}
which suggests to me you can have a protected abstract class in java. For that matter you can have a private abstract class.
Did you try to have a protected top-level class (not allowed)?
IMO, it does seem like an illegal modifier because protected means it should be visible in the package + in the derived classes. But in order to declare that some class extends this protected class you first need to be able to see it from there, which can't happen because it's visible only from the derived classes(given that super class and subclasses aren't in the same package).
If you only want to be able to see the class from other classes in the same package the default(package-private) modifier will work, no reason for the protected modifier to work - it only adds a completely unlogical and useless ability to see the class from its derived classes, which
a) can't happen if this class and its derived classes aren't in the same package.
b) can happen, given that this class and its derived classes are in the same package - this will work with the default (package-private) modifier anyway.
Top level classes cannot have protected scope, only public or package. Here's a nice reference explaining the allowable uses of scoping modifiers on classes.

Java class inheritance, private fields accessible in subclass, why?

I have code very much like the following.
package my.pkg;
public abstract class X {
private CapableField field;
public abstract void doSomething();
public X(CapableField fieldValue) {
this.field = fieldValue;
}
}
And:
package my.pkg.sub;
public class Y extends my.pkg.X {
public void doSomething() {
this.field.doSomething();
}
}
Why is this even legal code in Java? I thought "private" meant that the field will not be directly accessible in subclasses, and that this was a fairly basic tenet of class inheritance. Making X concrete instead of abstract changes nothing.
What do I do if I specifically want a field, or member function, to be accessible only inside the class where it is defined, and not in some random subclass of the defining class?
This is not true. Most likely you've actually definied Y as an inner class. This way the private fields of the outer class are indeed visible like that.
Doesn't compile for me too! I suspect your Java implementation.
This is impossible. May be you missed something when you explain your question.
private members are not visible in inheritance except in inner class scope. If you want them to be accessed by the subclass then declare them as protected. or use setters and getters.
and in your code you used package keyword in your package declaration which is not allowed and gives compilation error.
Make sure that your classes in two different files. for example X.java and Y.java and y not an inner class

Categories

Resources