Accessing overridden method of a private inner class with private constructor - java

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.

Related

java anoymous class can access private member of outer class. Why this code cannot access private data member?

I want to access private member of a class by anonymous class created in a different class.
I am new to java, kindly please explain this and tell what i am doing wrong.
class movie{
private String moviename="bahubali";
void display(){
System.out.println(moviename);
}
}
public class InnerClass{ //main class
public static void main(String[] args) {
movie anonymous=new movie() {
void display() {
System.out.println(moviename+" in anonymous class");
}
};
anonymous.display();
}
}
Your anonymous class inherits from the class movie (you should make it Movie instead btw. to comply with Java standards).
Inheriting classes are granted access to protected members, not to private members.
So the fix in this case should be changing
private String moviename="bahubali";
to
protected String moviename="bahubali";
.

Why would I combine a private constructor with a static nested class?

I'm currently digging a little bit into accessibility of Java classes. While there is a varity of possibilities to define classes, I wonder about a use case for the example below.
Basically, the constructor of AnotherClass is private. However, AnotherClass has a static nested class, which is accessible within the PublicClass class.
It's just something I came up with out of curiosity, but as it actually works, I wonder, why would I ever use something like this?
Example
public class PublicClass {
public PublicClass() {
AnotherClass.AnotherInnerClass innerClass = new AnotherClass.AnotherInnerClass();
innerClass.anotherTest();
}
}
class AnotherClass{
/**
* Private constructor - class cannot be instantiated within PublicClass.
*/
private AnotherClass(){
}
/**
* Static inner class - can still be accessed within package.
*/
static class AnotherInnerClass{
public void anotherTest(){
System.out.println("Called another test.");
}
}
}
Note those classes are within the same file.
Output
Called another test.
The AnotherInnerClass CAN use the private constructor of AnotherClass. This is used for example in the Builder pattern, which is something along the lines of this:
public class Foo {
public Foo() {
Bar.Builder barBuilder = new Bar.Builder();
Bar bar = barBuilder.build();
}
}
public class Bar{
private Bar(..){
}
static class Builder{
public Bar build(){
return new Bar(..);
}
}
}

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.

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

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();
}

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.

Categories