Java Inner class shadowing external class - java

I took the following code from the K&B book "SCJP Sun Certified Programmer for Java 6 Study Guide":
class A { // 1
void m() {
System.out.println("outer");
}
}
public class TestInners {
public static void main(String[] args) {
new TestInners().go();
}
void go() {
new A().m();
class A { // 2
void m() {
System.out.println("inner");
}
}
}
class A { // 3
void m() {
System.out.println("middle");
}
}
}
As stated in the book, this code prints "middle". I infer that the class declaration marked as "3" is shadowing the one marked as "1", which is external to TestInners class.
If the classes were in different packages, I could resolve the ambiguity by qualifying one of them with the package name. But in this case the classes are not only in the same package but in the same file. How can I get an instance of the external class?
I saw the same question here but the accepted answer implies to modify the code adding an enclosing class to the whole thing. My question is how to get the instance using any type of qualifier or reference, if it's even possible.

Assuming your class is in package com.test, all you need to do is use
new com.test.A().m();
using the fully qualified name of the class.
If your classes are in the default package, ie. no package declaration, then you are out of luck and can't access the outer A.

In C++, you can explicitly address global scope by prefixing your symbol with ::, however, Java does not have such a thing.
So if you really want to get the outer A, you have to bite the bullet and do some other sort of enclosure, by for example wrapping it in another class or package.
EDIT: Here is another reason why.

object of innner-A can't be created before defining it.so use new A().m(); after define innner-A inside go() to access inner class object.
void go() {
class A {
void m() {
System.out.println("inner");
}
}
new A().m();
}
to access outer-A you have to append package name,in default package it is impossible to access outer-A.

Related

Compile time error while accessing public variable in java main method

Can some one help what is wrong in this code? I have a parent class and child class created in java. I created a Parent class instance in Child class static main method. The public method is accessible, but not the public variable. Initially I thought this is something related to static scope. But that does not seem to be the issue. Because I am explicitly creating an instance of Parent class in the main method of child class. So ideally both variable and method should be accessible as I am explicitly creating an instance of Parent class in the static context. Strange thing is method is accessible without errors, but not the variable. Why the compiler is OK with the method but not with the variable? Ideally the error should be shown for both or not at all.
Both classes are in different package. But public scope is not going to be a problem even if the classes are in different packages I hope. Please find the below two classes..
package com.learning.scjp.examples;
public class ParentClass {
public String parentClassPublicVariable = "parentClassPublicVariable";
public void parentClassPublicScopeMethod(){
System.out.println("parentClassPublicScopeMethod");
}
}
=================================================================
package learning.access.classes;
import com.learning.scjp.examples.ParentClass;
public class ChildClass extends ParentClass {
public static void main(String[] args) {
ParentClass parentClass = new ParentClass();
parentClass.parentClassPublicVariable;//This statement shows compile time error "not a statement"
parentClass.parentClassPublicScopeMethod();
}
}
In general a statement in java is something that contains enough information to compile to translate the code into a meaninful action, something that can be executed by JVM.
Usually it can be:
Declaration statement (Example: int i = 0;)
Expression statement (Example: i++)
Control flow statement (Example: for(int i = 0; i < 10;i++))
The line:
parentClass.parentClassPublicVariable
is basically meaningless, it has no action, therefor compiler doesn't understand what should be done, its an error from the compiler's standpoint. Hence you have "not a statement" compilation error.
You can read about the statements here
You are able to access it just do it this way :-
class ParentClass {
public String parentClassPublicVariable = "parentClassPublicVariable";
public void parentClassPublicScopeMethod(){
System.out.println("parentClassPublicScopeMethod");
}
}
public class Try extends ParentClass {
public static void main(String[] args) {
ParentClass parentClass = new ParentClass();
System.out.println(parentClass.parentClassPublicVariable); // You can print it.
parentClass.parentClassPublicVariable = "StackOverflow"; // You can even reassign variable.
System.out.println(parentClass.parentClassPublicVariable);
parentClass.parentClassPublicScopeMethod();
}
}
Basically the line parentClass.parentClassPublicVariable; itself is useless and compiler is not able to understand it hence the error it had nothing to do with access modifiers or inheritance as you assumed.

Create a Class whose object can not be created

I am studying for my BS, and my professor has given me a task, he said: Create a class without using any access modifier or interface keyword whose object can't be created.
I went through Google but can't find the solution. How can this be done in Java?
Enums are classes (JLS§8.9) that cannot be instantiated and cannot be subclassed; just create one without any values:
enum Foo {}
Other possibilities depending on interpretation:
JonK and T.J. Crowder considered throwing an exception from the constructor:
final class Example {
Example() {
throw new Exception();
}
}
But nick zoum pointed out that an instance is still created and exists, briefly, prior to the exception, even though it cannot (in the example above) be retained.
nick zoum considered abstract:
abstract class Example {
}
...but T.J. Crowder pointed out that abstract classes can be subclassed (they cannot be final), and a subclass instance "is a" superclass instance.
I'm not a Java person, but other answers gave me this idea:
import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
Object o = new Problematic();
// unreachable
}
}
class Problematic
{
static
{
int i = 1 / 0 ;
}
}
Try it on ideone
I'm pretty sure there's no way of making a Problematic and surviving...
(Note that when I tried throw new Exception(); in the static initializer it wouldn't compile)
Have you tried the keyword abstract?
For example:
abstract class Test{}
Of course this can be overwritten, so please check this answer for a more foolproof design.
Without hearing exactly how your professor phrased it, "without using any access-modifier" might mean they are attempting to teach you how the "default" access modifier works?
In which case:
package mypackage.nocreate;
class MyClass {
}
And then:
package mypackage;
import mypackage.nocreate.MyClass;
public class Test {
public static void main(String[] args) {
new MyClass(); // not allowed - in a different package
}
}
You could argue that - in the source code at least - that doesn't use any access modifier :)
Anonymous inner class should be the answer.
Example:
public abstract class HelloWorld{
abstract void x();
public static void main(String []args){
System.out.println("Hello World");
HelloWorld h = new HelloWorld(){
void x(){
System.out.println(" ");
}
};
h.x();
}
}
A class is created, but it's name is decided by the compiler which extends the HelloWorld class and provides the implementation of the x() method.

How can i access one class variable into other

There are to separate classes class One and class Two. Both of classes are in same package. I want to access one class data into other class how can i access variable data. My program is very lengthy ,I just want the logic of this.Thanking you in advance.
Class A.java
public class A
{
public static void main(String ar[])
{
int a=100;
}
}
Class B.java
public class B extends A
{
public static void main(String m[])
{
A obj=new A();
System.out.println("Variable of class A is :"+ obj.a);
}
}
I have done this thing to get access like i declared variable a as Static so that i can directly get access but it's not working. and when i am compiling B.java It giving me error
cannot find symbol at := System.out.println("Variable of class A is :"+ obj.a);
And
Illegal start of expression (when i am delaring variable a as public)
:-(error)public int a=100; [in class A].
Why are you using the static main method? Besides that the field a is local and not accessible outside the scope. Use this instead.
public class A
{
public int a;
public A()
{
a=100;
}
}
You don't have two true object-oriented classes above, but rather little more than two receptacles for static main methods. To combine code from two classes well, you will want to scrap that code and make OOP-compliant classes, complete with instance fields and methods. For more on this, check out the OOP section of the Java tutorials: link to OOP tutorial.
First, get rid of main() in A. You only want one main() in your application, and it's in B (since the one in A doesn't actually do anything):
public class A {
}
Now, you want A to have a class-level int value:
public class A {
private int a;
}
And you want it to have a default value of 100, yes? A constructor is a good place to do that:
public class A {
private int a;
public A() {
this.a = 100;
}
}
Now any time you do this:
A obj = new A();
you will have an object with a value. In order to access that value from outside that object, you need a "getter":
public class A {
private int a;
public A() {
this.a = 100;
}
public int get_a() {
return this.a;
}
}
Now in B (or anywhere, really), you can create an instance of A and access that value by using the "getter":
A obj=new A();
System.out.println("Variable of class A is :"+ obj.get_a());
Semantically, don't think of it as "accessing a variable from another class". Instead, think of what your objects are and what they represent. If it were a physical, real-world object which internally contained some kind of value.
When you create an instance of that object, the instance would internally have that value somewhere. From the outside of that object, it doesn't really matter how that value is internally maintained. There just needs to be some kind of interface to see the value. Which is what the "getter" method does.
One-liner answer: To access a variable outside a class, make it class-level. You have written a method-level variable that's accessible only inside that scope (method).
To elaborate:
There are to separate classes class One and class Two. Both of classes are in same package. I want to access one class data into other class how can i access variable data.
So basically you know that to by extending, you should be able to access parent class data into your subclass. For that, simply make the data in your parent class as class level.
class A {
int var = 10; //class level, but non-static, so to access you need A object
void method() {
int var = 20; //this is method local and can not be accessed outside
}
}
public class B extends A {
public static void main(String[] args) {
A aObj = new A();
System.out.println(aObj.var);
}
}
Illegal start of expression (when i am delaring variable a as public)
Its illegal. Because access modifiers like public, private etc. are applicable to class-level stuff like the first var or the main method in class B you see.
Said that:
You need to immediately go here: https://docs.oracle.com/javase/tutorial/
rather than just trying to run some classes when you lack language basics.

Calling new on instance, like pc.new InnerClass() -- what is going on?

I'm puzzled by the possibility to call new on an instance, like
InnerClass sc = pc.new InnerClass();
I understand how to use it, but my question is about fully understanding this. Like:
Where is it described in the JAVA documentation?
Is this a recommended solution that should be used, or is there a better way?
Why doesn't a plain "new" work?
I saw it in a code example, and I have worked out enough to understand that I'm unable to use a plain "new" in a static context.
This is the full context as a runnable example:
class ParentClass{
ParentClass(){
}
public static void main(String[] args){
ParentClass pc = new ParentClass();
InnerClass sc = pc.new InnerClass();
}
class InnerClass {
InnerClass() {
System.out.println("I'm OK");
}
}
}
Disclaimer: The terms "parent class" and "sub class" you use are not correct in your example, so my example below will use the correct terms "outer class" and "inner class" (thanks to #eis for the hint).
Where is it described in the JAVA documentation?
See #eis' comment to my answer for a link.
Is this a recommended solution that should be used, or is there a better way?
It depends – on what you need it for.
If SubClass doesn't need any information of an instance of ParentClass, it could (and should) be either made static or extracted to not be an inner class at all anymore. In that case, you can just call new on it without having an instance of ParentClass.
Why doesn't a plain "new" work?
Because SubClass may refer to information of the surrounding instance, which requires you to specify that instance. It's not a sub class in the sense that it extends ParentClass, but instead its type becomes a member of the outer class.
Consider this (and see it in action here):
public class OuterClass {
private int field;
public OuterClass(int field) {
this.field = field;
}
class InnerClass {
public int getOuterClassField() {
// we can access the field from the surrounding type's instance!
return OuterClass.this.field;
}
}
public static void main(String[] args) throws Exception {
OuterClass parent = new OuterClass(42);
// prints '42'
System.out.println(parent.new InnerClass().getOuterClassField());
// cannot work as it makes no sense
// System.out.println(new InnerClass().getOuterClassField());
}
}
If you were able to simply do new InnerClass(), there's no way of knowing what getOuterClassField should return since it is connected to the instance of its surrounding type (rather than just the type itself).

Why isn't the Java compiler (specifically its parser) able to understand this statement

I have the following two classes (in two separate files).
public class Foo
{
public static class A
{
public static final boolean FLAG = false;
}
public final A A = new A();
}
public class Bar
{
void method()
{
if (Foo.A.FLAG) <<<< this is giving "Cannot make static ref to non-static field
// do something
;
}
}
My question is, why isn't the compiler able to recorgnise that by Foo.A, I meant the class A, not the member, which also happens to be named A?
This is called obscuring, an obscure feature/limitation of Java
A simple name may occur in contexts where it may potentially be
interpreted as the name of a variable, a type, or a package. In these
situations, the rules of §6.5 specify that a variable will be chosen
in preference to a type, and that a type will be chosen in preference
to a package. Thus, it is may sometimes be impossible to refer to a
visible type or package declaration via its simple name. We say that
such a declaration is obscured.
If the variable A was static, it would compile since you can can access static members on object references.
Also FLAG hasn't been initialized.
Some ways to access the flag:
<Foo_A extends Foo.A> void test1()
{
if(Foo_A.FLAG)
;
}
void test2()
{
class Foo_A extends Foo.A{}
if(Foo_A.FLAG)
;
}
-------------------------------------
import pkg.Foo.A;
public class Bar
{
void test3()
{
if(A.FLAG)
;
}
}
in these contexts, "Foo.A" can only be interpreted as a type, not a variable.
Because inner classes require an instance of the enclosing type. If you dont have an instance of Foo, A doesnt exist.
Edit - This is incorrect, but the reason why is informative. see the comments below:

Categories