Accessing static classes in another java file - java

Is it possible that I can access a static class in another *.java file?
My scenario is that I have two java files in the same folder, A.java and B.java:
In A.java, which does not only include class A but static class C:
public class A {
public static void main(String[] args) {
//code
}
static class C{
//code
}
}
In B.java, which will use methods of class C:
public class B {
//code, use C's methods
}
In the file B.java, I want to use class C's methods declared in the A.java; however, the compiler does not recognize the class C, even though I put the A.java and B.java in the same folder. I suppose I do not need to import anything because both java files are in the same folder, doesn't it? Does anyone know how to solve this problem? Thank you!

Please note that class C has no access modifier and will only be visible in the same package. To clarify: A subclass won't inherit access modifiers from its encapsulating class.
If A and B are on the same packages you can access C from B by using A.C.<code> If you would like to make C available to classes outside of A's package you need to make the subclass C public:
// [...]
// insead of >>static class C {<<
public static class C {
// [...]
After you've changed the access modifier you can use C as mentioned above (A.C.<code>)

Related

Can't see class from within a package

I have a Java project built using IDEA and Maven. To make this question simple:
suppose part of the structure of the project is
src -> main -> java
In java folder there is a package called PAK, for example, which contains class A. Also there is class B in java folder without package.
The problem is when I'm trying next code
package PAK;
public class A {
private B variable;
}
compiler can't see class B but class B is public.
You need to import the class B, because it's not in the same package with A
package PAK;
import B;
public class A {
private B variable;
}
If classes are in the same package, you don't need to import them.

$ symbol in .class files

I have a program called MyProgram.java. I want to run it from different directory which will be run on another machine. So I made a directory and copied MyProgram.class file and made a .bat file that runs it (Run.bat) which includes the command: #java MyProgram.
This didn't work, I had to copy SPVerification$1.class that was generated from Eclipse in order to make it work.
What is this XXX$1.class files and why do I need them beside the XXX.class file in order to run an application?
If your .java file have inner/nested classes , post compilation those are generated as Yourclass$xxx.class files by the java compiler.
Inner class definitions produce additional class files. These class
files have names combining the inner and outer class names, such as
MyClass$MyInnerClass.class. - Source
Example (edit)
Considering following Class definition
// MyClass class
public class MyClass{
// Inner class Test1
class Inner1 {
}
// Inner class Test2
class Inner2{
}
public static void main(String [] args) {
// Anonymous inner class 1
new Object() {
};
// Anonymous inner class 2
new Object() {
};
System.out.println("Bunch of $ files :)");
}
}
Will generate these following Files
MyClass.class
MyClass$Inner1.class
MyClass$Inner2.class
MyClass$1.class
MyClass$2.class
They are anonymous inner classes. In other words, when you have a piece like
class OuterClass {
// ...
void method() {
Thread t = new Thread(new Runnable() {
// ... code implementing Runnable interface ...
});
// ... code to use t or whatever
}
}
That generates anonymous inner class, in this case implementing the Runnable interface, and compiled code of that class goes to a OuterClass$<number>.class file. You can have more than one such class, with increasing number in the .class file name.
Note that syntax is exactly the same even if you extend a class with the anonymous inner class, instead of implementing an interface. This is a slightly different from creating named classes, where you need to use implements and extends as appropriate.

declare multiple class using Eclipse

is there a way to declare 2 classes on the same .java file using Eclipse - also how the compiler will distinguish the .class for each declare class.
example
public class ThisTest
{
public static void main(String[] args)
{
}
}
class SimpleArray
{
}
thank you for your time.
is there a way to declare 2 classes on the same .java file using Eclipse
Yes, you can have several classes defined in a single .java file, but there may at most one public class in each file. (Just as in your example.)
Note that if you have a public class in a .java file, the name of that class must be the same as the name of the .java file.
how the compiler will distinguish the .class for each declare class.
The names of the .class files does not depend on the name of the .java file, but on the identifiers of the class declarations.
If you have
class A {}
class B {}
in a file named Classes.java, you'll get A.class and B.class if you compile it.
Yes, exactly like your example.
The extra class need to be non-public
You could also define inner/nested classes. In this case you should investigate the difference
Java inner class and static nested class
public class ThisTest
{
public static void main(String[] args)
{
}
static class SimpleArray
{
}
class SimpleArray2 {}
}
class Buddy {}
Each class will be located in an own .class file in a directory similar to the package.
Nested classes get its host prefixed and separated by an '$'.
The above case results in four class files
ThisTest.class
ThisTest$SimpleArray.class
ThisTest$SimpleArray2.class
Buddy.class
Just check the bin or classes folder of your eclipse project.

java decompilation

When decompiling a specific jar using java decompiler (http://java.decompiler.free.fr/) I got some strange code I cannot identify what is. can someone help me? the code is something like:
Foo.access$004(Foo.this);
or this
Bar.access$006(Bar.this);
or else
Baz.access$102(Baz.this, true)
What are these methods access$004, access$006 and access$102?
Synthetic methods like this get created to support acessing private methods of inner classes. Since inner classes were not part of the initial jvm version, the access modifiers could not really handle this case. The solution was to create additional package-visible methods that delegate to the private implementation.
public class Example {
private static class Inner {
private void innerMethod() { ... }
}
public void test() {
Inner inner = ...
inner.innerMethod():
}
}
The compile would create a new method of the Inner class like this:
static void access$000(Inner inner) {
inner.innerMethod();
}
And replace the call in the test method like this:
Inner.access$000(inner);
The static access$000 is package visible and so accessible from the outer class, and being inside the same Inner class it can delegate to the private innerMethod.
These are auto-generated methods which are created by the compiler in some cases (for example when accessing private fields of another class directly, e.g., in case of nested classes).
See also What is the meaning of "static synthetic"? and Synthetic Class in Java.
If you get the relevant .class file (run jar through unzip), and run the .class file through JAD
JAD MyClass.class
then you may find that the output JAD file has decompiled that particular line in a more meaningful way, e.g.
Baz.access$102(Baz.this, true)
shows up in the JAD output as simply
myMemberVaiable = true
where myMemberVaiable is a member of class Baz that you will recognise.

Restricting access to package private variables when the package is used in other package

company xyz created a package
com.xyz.utils.
There are two classes declared in two separate files. They have some variables as package private. so that a variable X in class A can be used in class B of the same package.
package com.xyz.utils;
public class A{
int a=10;
}
package com.xyz.utils;
public class B{
int b = (new A()).a;
}
Those two files are compiled into a jar and sent to customer.
The customer add the jar to the project he is building and he writes code like below
package com.xyz.utils;
public class customer_class
{
int Y = (new A()).a;
}
Is that above code is correct?
My quetsion is. how can we make variables which are declared as package private to be not visible to others when they use the package.
The answer is "no" - you can't stop them from doing that.
It can not be done in general. I think, you can seal the package 'com.xyz.utils' in in the jar manifest, to tell the user that: do not define their classes in the sealed package as a best practice. But you can not restrict the user of your library from doing it.

Categories