In one directory, I have defined the following file A.java:
package test;
public class A {}
class B {
public void hello() {
System.out.println("Hello World");
}
}
From a different directory, if I do the following:
import test.B;
public class X {
public static void main(String [] args) {
B b = new B();
b.hello();
}
}
and compile javac X.java, I get the following error:
X.java:2: test.B is not public in test; cannot be accessed from outside package
import test.B;
^
X.java:7: test.B is not public in test; cannot be accessed from outside package
B b = new B();
^
X.java:7: test.B is not public in test; cannot be accessed from outside package
B b = new B();
^
I cannot change the sources in package test. How do I resolve this?
In Java, there are 4 different scope accessibilities:
Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N
In your case, B has no modifier, which means it can be seen inside the class and inside the package only. Therefore, if you create class X that is an other package, it won't see B.
To acess B, you need to define a class that is inside the same package as B which in your case is the package test.
Default access modifier OR no modifier specified member is only accessible in declared package but not outside the package.So in your case B is only accessible inside package named test. Read more on Access Modifiers.
If you cannot change the sources in package test.Than move your code/class to test package.
Use reflection:
package test2;
public class Main {
public static void main(String[] args) throws Exception {
java.lang.reflect.Constructor<?> bConstructor = Class.forName("test.B").getConstructor(/* parameter types */);
bConstructor.setAccessible(true);
Object b = bConstructor.newInstance(/* parameters */);
java.lang.reflect.Method hello = b.getClass().getMethod("hello");
hello.setAccessible(true);
hello.invoke(b);
}
}
Related
protected fields of a class are accessible from a subclass in a different package, then why the code shows "The field A.x is not visible?"
// A.java
package pack;
public class A {
protected int x;
public A() {}
public A(int x) {
this.x = x;
}
public void showx() {
System.out.println(x);
}
}
// B.java
package pack2;
import pack.*;
public class B extends A {
public static void main(String[] args) {
A a = new A(5);
System.out.println(a.x); // The field A.x is not visible
a.showx(); // 5
}
}
You are answering your own question.
"Protected fields of a class are accessible from a subclass in a different package;
In your case B is the subclass of A.You can access x via
B b = new B();
System.out.println(b.x);
Otherwise it will behave like a private access modifier;
I need to pass an argument between two classes in different packages.
For example, I have an int a in class A in package AA.. I need to pass it to class B in package BB which will change the value of a and pass it back to class A.
Either Use fully qualified class name or import it in another program . E.g if you want to create an object of class A which is in AA package in class B which is in different package, use
AA.A obj = new AA.A();
Now call the method which you want to pass value to, using this obj reference variable.
The above code did not work for me. I had to change the import in package B to make it work.
package BB;
import AA.A;
public class B {
public int change_a(int a){
return a+1;
}
}
You should be passing arguments like this
package AA;
import BB.B;
public class A {
int a = 5;
private void play() {
B b = new B();
// Here we are passing the int argument to a method in different class and different package
int new_a = b.change_a(a);
System.out.println("a after the change is "+ new_a);
}
public static void main(String[] args){
new A().play();
}
}
And your class B
package BB;
import BB.A;
public class B {
public int change_a(int a){
return a+1;
}
}
I would like to know how the default package is defined in Java.I know how public and private access is defined but I don't know whether there is any default package access that is defined in package level access in java.
The code I tried to execute is:
class A
{
public static void value()
{
int a;
a=5;
}
public static void main()
{
value();
}
}
class B
{
public void greet()
{
System.out.println("Value of a is"+a);
}
}
The error I got is:
D:\Downloads\pro>javac A.java
A.java:17: error: cannot find symbol
System.out.println("Value of a is"+a);
^
symbol: variable a
location: class B
1 error
Since both classes belong to the same default package shouldn't class B access class A's members(a)?
I'm asking this question because when I compile java file containing two classes since no modifier is given for classes,java compiler would give package level access as the default access modifier for the classes.Since no package is defined,java compiler would use the default package but I couldn't get whether the default package is included in package level access in java.Could anyone help me.
a is a variable inside the static function value and not visible outside of that function at all. Doesn't have to do with access specifiers.
The default package is the package without a name, all classes without a package declaration at the top of the file fall into it.
It is subject to all normal rules of packages except that you can't reference classes of it from a class inside a package.
For example I have 2 java files:
public class A{
public static void foo(){System.out.println("fooCalled");}
}
and
package com.example;
public class B{
public static void main(String[] arg){
A.foo();//won't compile
}
}
Then B (or in the qualified form com.example.B) can never call the foo of A without reflection magic.
Your program has nothing to do with access specifiers, as you have declared your variable int a inside a method.
Thus it becomes just a local variable. You cannot even use it outside this method in the same class.
If we talk specifically about access specifiers then we can have default access specifier in Java which has scope up to the same package only.
package com;
class A{
int a; // this is an instance variable
static int b; //this is a class variable
}
package com;
class B{
//can use a variable here
// To use a here, we need new A().a;
// To use b here, we can do, A.b
}
package hello;
class C{
//can't use a variable here
}
Edit
Suppose we create a file with name MyProgram.java on Desktop. Below is the code of this file,
class First{
int a; // a is an instance variable
static int b; // b is a static (class) variable
void display(){
int c; // c is a local variable
}
}
class Second{
public static void mian(){
First obj = new First();
obj.a = 10; // to access instance variable we need object of the class
obj.b = 20; // class variable can also be accessed using the object
// First.a = 10; //It won't work as a is instance variable and can be accessed by object only
// First.b = 20; // We can also access static variables by class name directly without using any object
// obj.c = 30; // It won't work. As c is a local variable of method display and can be used only inside that method.
// First.c = 30; //It also won't work as c can only be used inside the method where it is declared.
}
}
So finally I got how we could access an variable in another class without creating an object provided both classes rest in the same package.Just make the variable static.
Here's the code:
import java.io.*;
class A
{
static int a=5;
public void turn()
{
System.out.println("value of a is"+a);
}
}
class B
{
public static void main(String args[])
{
int b;
b=A.a;
System.out.println("value of a is"+b);
}
}
This shows that classes residing in the same package can access each other's members provided it is static even though it is not public because default package access comes to play.
Default access modifier means we do not explicitly declare an access modifier for a class, field,
method, etc.
A variable or method declared without any access control modifier is available to any other
class in the same package. The fields in an interface are implicitly public static final and
the methods in an interface are by default public.
In your class B, a is not defined.
class B {
public void greet() {
System.out.println("Value of a is" + a );//cannot find `a` inside `B`
}
}
Now coming to accessibility, since your both classes are in same package B class can access public, protected and default(no access modifiers) members of other class like A. But in your case a is a local variable inside the A member method value(), so a variable cannot be accessed outside the method where it was declared.
class A {
public static void value() {
int a;//not accessible outside this method
a=5;
}
public static void main() {//FYI: this main is not valid to execute your code, missing here: `String[] args` argument
value();
//`a`, is even not accessible here, forget about class `B`
}
}
Sample code, all are in same package:
class A {
String bar;
}
class B {
public foo() {
A a = new A();//required, as `bar` is instance(non-static) member of class `A`
a.bar 'hi there';//set value
System.out.printf("a.bar = %s\n", a.bar);
}
}
EDIT
Sample code with nested class:
class A {
int foo;
class B {
void setFoo() {
foo = 45; //accessing member of class `A`
}
}
}
Working code:
<pre>
<code>
class A {
private int foo;
private B b;
A() {
foo = -1;
b = new B();
}
class B {
void setFoo(int foo) {
System.out.printf("Inside B's setFoo(), foo = %d\n", foo);
A.this.foo = foo; //accessing member of class `A`
}
}
int getFoo() {
return foo;
}
public void setFoo(int foo) {
System.out.printf("Inside A's setFoo(), foo = %d\n", foo);
b.setFoo(foo);
}
}
class Ideone{
public static void main (String[] args) {
A a = new A();
System.out.printf("main(), foo = %d\n", a.getFoo());
a.setFoo(34);
System.out.printf("main(), foo = %d\n", a.getFoo());
}
}
</code>
</pre>
I want to create an instance of class B that isn't a part of A's inner class.
How can I achieve this? I'd like the class name to remain the same for both B classes.
public class Sample {
public static void main(String[] args) {
A a = new A();
a.show();
}
}
class A {
class B {
public void show() {
System.out.println("hello");
}
}
public void show() {
B b = new B();
b.show();
}
}
class B {
public void show() {
System.out.println("hellohello");
}
}
Use full qualified name of class B, i.e. com.mypackage.mysubpackage.B for outer B and com.mypackage.mysubpackage.A.B for inner B.
You can use the fully-qualified name of B to always refer to it: packageName.B.
This won't work if the class is in the unnamed (default) package (i.e. if there is no package declaration on top of its .java file). This is yet another reason not to use the unnamed package at all (i.e. all your classes should be in a named package).
Use the complete identifier of the class you want to create an instance of (no import statement).
yourPackage.B variable = new yourPackage.B();
Replace your main method with the code below:
public static void main(String[] args) {
A a = new A();
a.show();
//For Outer Class
B bOuter =new B();
bOuter.show();
//For Inner Class
A.B bInner=new A().new B();
bInner.show();
}
Use complete qualified name to keep away from conflict among same classes name.
E.g. packageName.A.B and packageName.B
I am try to find out why below code is giving error, Can anybody explain please.
Here is a class
package abc;
public class A {
public class B {
}
}
Now I am try to create a B class
package xyz;
import abc.*;
public class B extends A{
public static void main(String[] args) {
B b = new B (); // this line gives error. Can you please explain
}
}
Please consider class B extends A is in default package means
import abc.*;
public class B extends A{
public static void main(String[] args) {
B b = new B (); // this line gives error. Can you please explain
// I am try to create "B" class object which extends A
//.. not the B inner class
}
}
Error shows in eclipse is : "No enclosing instance of type A is accessible. Must qualify the allocation with an enclosing instance of type A (e.g. x.new A() where x is an instance of A)."
Given that B extends A, and A contains an inner class B, I suspect there's room for confusion (for both compiler and programmer).
The line:
B b = new B();
is ambiguous. Which B is this ? As pointed out elsewhere, the inner class B needs an containing instance of A, so I suspect you mean the B outer class.
Edit: Your error
"No enclosing instance of type A is accessible. Must qualify the
allocation with an enclosing instance of type A (e.g. x.new A() where
x is an instance of A)."
confirms this. I presume you want the xyz.B and should scope that appropriately.
Try to specify the enclosing scope:
B b = new A.B();
or
B b = new xyz.B();
If you make public class B static, it will work as written.
Otherwise, you cannot make instances of class B from outside an instance of class A, because non-static inner classes require a pointer to their outer class's "this" (within a B, you can write this.A, and that will actually refer to the enclosing A).
When I create the following in Eclipse:
package com.example;
public class A {
class B {
}
}
and
package com.example;
import com.example.A.B;
public class B extends A {
public static void main(String[] args) {
B b = new B();
}
}
As you can see Eclipse imports the class A.B . Without the import the following error is noted:
No enclosing instance of type A is accessible. Must qualify the allocation with an enclosing instance of type A (e.g. x.new A() where x is an instance of A).
The error I get when I try to compile this code (minus the package specs since they seem irrelevant) is "non-static variable this cannot be referenced from a static context". So, the problem is that within the static method main() you are trying to access something non-static, which I guess is the definition of the inner class B.
You actually get the same error if the second outer class has a different name. So the apparent naming conflict is a red herring. Although that itself is a good reason not to use the same name for both classes -- it causes confusion when trying to understand the error.
If I change the declaration of the inner class to be static, the error is resolved.
public class A {
public static class B {
}
}
Some relevant discussion of static vs. non-static nested classes is here.
But this may not be the correct fix. It shows that your code in main() is referencing the B inner class, not the B class that contains the method. Which did you actually want? Obviously, I'd suggest using different names for this two classes to avoid confusion. If what you want in main() is to create an instance of the class that contains that method, then using a unique name for that class will solve your problem.
Your class B extends A has inherited the class A.B and the expression new B() refers to that inner class. Therefore it asks for an enclosing instance. You must either explicitly qualify both your mentions of B with the package name, or, far better, avoid such naming mess in the first place.
I found this solution, through reflection you can create B class(B extends A class) object.
import java.lang.reflect.Method;
import abc.*;
public class B extends A{
public static void main(String[] args) {
//B b = new B(); // this line gives error. Can you please explain
// I am try to create "B" class object which extends A
//.. not the B inner class
try{
Class c = Class.forName("B"); //class B extends A
Method m=c.getMethod("print", null);
m.invoke(c.newInstance(), null);
}catch(Exception e){
e.printStackTrace();
}
}
public void print(){
System.out.println("Printed");
}
}