Get the class-name of a Java inner class' outer class instance - java

abstract class Base {
...
public class Inner {
private final String ownerClassName;
public Inner() {
...
}
}
public static class Super1 extends Base{
...
}
public static class Super2 extends Base{
...
}
}
I would like Inner.Inner() to set ownerClassName to the type of the enclosing class instance, e.g. "Super1" or "Super2".
How can this be done?

Base.this.getClass().getName()

First remove final from ownerClassName, make it private and provide only get method if you want.
Then follow the code:
Inner() {
ownerClassName = Base.this.getClass().getSimpleName();
}

Related

Accessing overridden method of a private inner class with private constructor

Please find the below snippet :
class Rule
public class Rules {
public static final JarvisFilterRule FILTER = new JarvisFilterRule();
private static class JarvisFilterRule extends RelOptRule {
private JarvisFilterRule() {
super(operand(Filter.class, operand(Query.class, none())));
}
public void onMatch(RelOptRuleCall call) {
// do something
}
}
}
class RelOptRule
public abstract class RelOptRule {
/**
* Description of rule, must be unique within planner. Default is the name
* of the class sans package name, but derived classes are encouraged to
* override.
*/
protected final String description;
public abstract void onMatch(RelOptRuleCall call);
}
My question is : How can I access the onMatch() method of nested class Rules.JarvisFilterRule?
The purpose of the private key word is to prevent access to class members that need to be used exclusively by the class declaring it.
In your case, the Rules class defines JarvisFilterRule to be a private inner class with the intention that its implementation should be known only to the Rules class.
If you wish to access the JarvisFilterRule::onMatch() method inside another class, you will need to replace the private modifier of JarvisFilterRule with public or move the inner class JarvisFilterRule to its own separate file and make it a public class. Like this:
JarvisFilterRule .java
public class JarvisFilterRule extends RelOptRule {
public JarvisFilterRule() {
super(operand(Filter.class, operand(Query.class, none())));
}
public void onMatch(RelOptRuleCall call) {
// do something
}
}
-- OR --
public class Rules {
public static final JarvisFilterRule FILTER = new JarvisFilterRule();
public static class JarvisFilterRule extends RelOptRule {
private JarvisFilterRule() {
super(operand(Filter.class, operand(Query.class, none())));
}
public void onMatch(RelOptRuleCall call) {
// do something
}
}
}
Hope this helps!
Rules.FILTER.onMatch(...)
JarvisFilterRule is not an inner class. An inner class in Java is a nested class that is not static.

when you extend a private class. are the public and protected members of class become private

when you extend a private class. Are the public and protected members of class become private. if not any explanation.
if you extend a nested private class, it wont change public/protected modifiers of the members. Here is an example :
public class Clazz {
private static class NestedClazz {
public int value = 123;
}
public static class NestedClazzExt extends NestedClazz {
}
}
you can now access the inherited member: value from outside
public static void main(String[] args) {
NestedClazzExt nestedClazz = new Clazz.NestedClazzExt();
System.out.println(nestedClazz.value);
}
you can create private class in side a class . We call it as Nested classe. Means a class inside a class. The Concept itself is saying that you can create private class in side another class. The private class will act like as data member to the outer class.
So, You can't extend the private class.
Based on your query I tried to prepare a simple class.
public class pvtClass {
private class As {
public String abc = "private attribute";
public void print(){
System.out.println("privateClass");
}
}
class Ab extends As{
public String ab = "extended attribute";
public void printAb(){
System.out.println("extended class");
print();
System.out.println(abc);
}
}
public static void main(String as[]){
Ab ab1 = (new pvtClass()).new Ab();
As as1 = (new pvtClass()).new As();
ab1.printAb();
as1.print();
System.out.println(as1.abc);
}
}
If you have a look at this class, I have a private class named "As" which has public attribute and public methods. I have another class named "Ab" which extends "As". I have written a main method to invoke the private attribute and methods.
below is the output for the code snippet:
extended class
privateClass
private attribute
privateClass
private attribute
There is a difference between the access of the members of a class and the access to the type itself.
public class C {
private class InnerP1 {
public void m() {
System.out.println("InnerP1.m()");
}
}
private class InnerP2 extends InnerP1 {
public void p() {
this.m();
System.out.println("InnerP2.p()");
}
}
public InnerP1 strange() {
return new InnerP2();
}
}
In this example, the interface I is visible from outside class C. The classes InnerP1 and InnerP2 are not visible from outside C. Jave itself makes not restrictions to the visibility of types you use in your public interface. The method strange() of class C returns a result of class InnerP1. Since outside of C we do not know anything about the class InnerP1 other than it is subtype of Object, the only thing we can do is use the result of strange() as an Object.
public class D {
public static void main(String[] args) {
C c = new C();
Object o = c.strange();
if(o.equals(c.strange())) {
System.out.println("Strange things are going on here!");
}
}
}
As #KnusperPudding pointed out already, the visiblity of public members is not changed, we might just not have enough knowledge of the type itself to access them.
Access to members cannot be restricted by sub-classing. When you mark a class as private then access via the class name is restricted i.e. to the same .java file, however once you have an instance of this class it can be accessed at least as easily as the super class.

How to access a public method in a private static inner class from another class?

How to access the public function of private static inner class in some other class Suppose there is a class structure like below :-
public class Outer{
private static Inner {
public void func() {
}
}
}
And there is another class :-
class UseFunc {
// I have to use the func() here
}
If I use like this it will give error : - create object of Inner like Outer.Inner oi = new Outer.Inner();
access oi.func() //as Inner is private class
Okay, this is a very bad (I mean, really terrible) implementation but it works:
public class Outer
{
private static class Inner
{
public void func()
{
}
}
public void encapsulatedFunc()
{
new Inner().func();
}
}
class UseFunc
{
public static void main(String[] args)
{
new Outer().encapsulatedFunc();
}
}
I can only imagine that code being used for educational purpose as a "What not to do" example.

scope of private constructor in Nested Class

This is more of a puzzle than question. I have the following code:
public class PrivateBaseConstructor {
public static class BaseClass {
private BaseClass() {
}
}
public static class DerivedClass extends BaseClass {
public DerivedClass() {
super(); // 1*
}
}
}
Here the call for super(); at 1* is allowed even though the base class constructor is private. If we write the classes as separate classes in same package:
BClass.java
public class BClass {
private BClass() {
}
}
DClass.java
public class DClass extends BClass {
public DClass() {
super(); // 2*
}
The compiler rightly gives an error at 2* since the base class constructor is not visible.
Why doesn't the compiler throw an error in my first scenario when both the classes are declared static within one class?
if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6.1
Because nested classes can see each others members. This has nothing to do with the static declarations. See the following example of your code with just nested inner classes (not static).
public class PrivateBaseConstructor {
public class BaseClass {
private BaseClass() {}
}
public class DerivedClass extends BaseClass {
public DerivedClass() {
super(); // 1*
}
}
public static void main(String[] args)
{
new PrivateBaseConstructor(). new DerivedClass();
}
}
Read more about nested classes here: http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
Because anything declared inside a class can access its private members, including inner classes. However, if you run PMD on your class, you'll find it suggests you change the visibility of the constructor to not-private.

private constructor in abstract class scenario

Is there is any feasible solution to have private constructor in abstract class..please advise
public abstract class BaseClass
{
private String member;
private BaseClass(String member)
{
this.member = member;
}
... abstract methods...
}
abstract class can have a private constructor. But that class cannot be extended by another class. Instead of adding a static inner class inside the abstract class and extends that abstract class.
abstract class Base{
public abstract void set();
private Base(){
System.out.println("Private Constructor!");
}
static class Derived extends Base{
public void set(){
System.out.println("set() method implemented!");
}
}
public static void main(String[] args){
new Base.Derived().set();
}
}
This defeats the purpose of abstract classes:
An abstract class must be subclassed to be used.
If a method is private, the subclass can't see it.
∴ It's effectively unreachable.
So, no.
EDIT #yshavit has found a hole in this logic which is very true - have a look at his comment (which should probably be an answer to the question?).

Categories