I am stuck on an assignment question where the task is only to break-down a single java file containing multiple classes into multiple java files and then import these java files so that the original project still works.(4 classes in total, moving 3 of them to separate files)
I create a new Project and move one class to that new project. Then import it to my original file and set the necessary functions to public and it works.
For the other two classes, I have to make a new Project with a completely different name(say Five) and paste the clases Three and Four into this Project. And then import these two classes into the original file.
I do that and it says the classes Three and Four should be public. That however is not possible since the class Five is already public. How do I access these two classes from the original file?
Project One: (This is the one im trying to run)
package one;
import two.Two;
import five.Five;
public class One {
public static void main(String[] args) {
...
}
)
class Customer{
...//this class accesses attributes and methods of classes
//Two, Three and Four. The error occurs for methods from classes Three and Four
}
Project Two
package two;
public class Two {
public static void main(String[] args) {
...
}
)
Project Five
package five;
public class Five {
public static void main(String[] args) {
...
}
}
class Three{
...
}
class Four{
...
}
Take a look at this question (and answer): Can a java file have more than one class?
You can only have one public class per file. If you don't want Three and Four as inner static classes in Five, you must put them in separate files Three.java and Four.java.
Also, package can be equivalent to a folder, so if your classes are in the same folder (part of one module/logic unit) they can all be in the same package, say main.
Thus your package main will contain all classes in a Java file each (it's also the good practice, unless a class is logically a sub-unit of another class). Also note that no imports are required in classes in the same package. They don't even have to be public.
as in above answer in one .java file has only one public class we cant make other class public so, other classes cannot be access by the classes of different packages because those classes are default and their visibility only in it's package. other package cannot access those classes.
But if you really want to do below example is one of the way to do that.
package pack1;
public class A {
public void sum(int a, int b){
System.out.println("Addition of a and b ="+(a+b));}
public static class Sub
{
public void subtraction(int a, int b)
{
System.out.println("subtraction a-b ="+(a-b));
}
}
}
// below main class is written and in that main class we are accessing the above classes of pack1
package mypack;
import pack1.*;
public class B {
public static void main(String[] args) {
A o1=new A();
int a=50,b=20;
o1.sum(a,b);
A.Sub o2=new A.Sub();
o2.subtraction(a,b);
}
}
Related
This question already has answers here:
What does "Could not find or load main class" mean?
(61 answers)
What is the purpose of defining a package in a Java file? [closed]
(11 answers)
Closed 6 months ago.
I am just starting to learn Java. I have made a project of Java using Visual Studio Code. The file path looks like this project/src/own/test.java.
I have written a simple program:
package own;
import java.util.Random;
import java.util.Scanner;
import static java.lang.System.out;
public class test {
public static void main (String[] args){
int randomNumber = new Random().nextInt(7);
System.out.println("Enter a number");
Scanner keyboard = new Scanner(System.in);
int inputNumber = keyboard.nextInt();
if (randomNumber == inputNumber){
System.out.println("You won!");
}else{
System.out.println("You loose!");
}
keyboard.close();
}
}
Every time I run this is the vscode terminal, it says:
Error: Could not find or load main class test
But it runs fine if package own; line is not there. Vscode automatically included this line. Can anyone tell me why that is so? What is the use of package own.
Classes in Java almost always have to specify their "package...". Almost because there are some exceptions.
This reserved word is used for several important things, such as:
With package you identify in which zone of the project your class is located, in general, each java project has src/main/java/mypackage
src, main, and java are directories, not packages (you can look up the difference between these). So the classes here will not have a package, you can execute a main method but this class will be invisible inside your project
If you are at the "mypackage" level, from this path the class is already visible inside your project and the class will carry the "package mypackage";
By having your class with "package mypackage;" you can import this class to another class, and use the methods of the first class in the second class
package mypackage;
public class ClassOne {
public static String goodMorning(){
System.out.println("good morning");
}
}
And this class is in another file
package mypackage;
import mypackage.ClassOne;
public class ClassTwo{
public static void main(String args...){
ClassOne.goodMorning();
}
}
If you know PHP it works similar to "require_once" (although they are similar import and require_once do not work the same)
I mentioned above about "visibility" and it is that packages are also used to know the scope of an access modifier, in java there are 4 of these: public, private, protected and default (by default it is when you do not put an access modifier )
//public access modifier
public class One{
public String attribute;
public void method(){
}
}
//private access modifier
private class Two{
private String attribute;
private void method(){
}
}
//protected access modifier
protected class Three{
protected String attribute;
protected void method(){
}
}
//default access modifier
class Four{
String attribute;
void method(){
}
}
Find out what each one is for.
And another thing it is useful for, is organizing classes by packages, you can organize a collection of classes in a better way, this is important for large projects.
There are still more things but as you say that you are learning I do not want to overload you with information, go easy, greetings.
Constraints:
I have a maven source code generator that I wrote that is creating POJO classes
from some data files that have nested namespaces. I want each namespace to
be nested as an inner class. In some cases out of my control I end up
with inner classes that are the same simple name as the outermost
class.
All the classes must be public scope as this is for a type safe
wrapper over something like a properties file, but hierarchical..
I can't change the names otherwise I am changing the names meaning and the namespace
that is enclosing data.
Given than I have the following code:
public class A
{
public class B
{
public class A
{
}
}
}
Inner classes should append the name of the outer class to form a unique namespace such as A$B$A.class, I haven't found a valid reason for this not to compile.
Is there any trick to get this to compile?
No. From the JLS section on class declarations:
It is a compile-time error if a class has the same simple name as any of its enclosing classes or interfaces.
Note: I somehow managed to miss this on my first pass through looking for an explicit rule. Check the edit history if you want the tortuous way I got here.
You asked: Is there any trick to get this to compile?.
The answer is: Well, maybe....
Create a class like the following:
public class A
{
public class B
{
public class X
{
}
}
}
And a class where this class is going to be used
public class AUse
{
public static void main(String[] args)
{
A.B.X aba = new A().new B().new X();
System.out.println("Created "+aba+" of class "+aba.getClass());
}
}
Then, download the Apache Byte Code Engineering Library (BCEL), and create and run the following class:
import java.io.FileOutputStream;
import org.apache.bcel.Repository;
import org.apache.bcel.util.BCELifier;
public class CreateCreators
{
public static void main(String[] args) throws Exception
{
new BCELifier(
Repository.lookupClass("A"),
new FileOutputStream("ACreator.java")).start();
new BCELifier(
Repository.lookupClass("A$B"),
new FileOutputStream("A$BCreator.java")).start();
new BCELifier(
Repository.lookupClass("A$B$X"),
new FileOutputStream("A$B$XCreator.java")).start();
new BCELifier(
Repository.lookupClass("AUse"),
new FileOutputStream("AUseCreator.java")).start();
}
}
This uses the BCELifier class from the BCEL. This is a class that takes a .class file, and creates a .java file that can be compiled to a .class file, that, when it is executed, creates the .class file that it was originally fed with. (Side note: I love this library).
So the A$B$XCreator.java file that is created there contains the BCEL code that is necessary to create the A$B$X.class file. This consists of statements like the generation of the constant pool and the instructions:
...
_cg = new ClassGen("A$B$X", "java.lang.Object", "A.java",
ACC_PUBLIC | ACC_SUPER, new String[] { });
...
il.append(_factory.createFieldAccess("A$B$X", "this$1",
new ObjectType("A$B"), Constants.PUTFIELD));
Similarly, the AUseCreator.java contains the BCEL code that creates the AUse.class. For example, the instruction of the constructor invocation of `A$B$X':
...
il.append(_factory.createInvoke("A$B$X", "<init>", Type.VOID,
new Type[] { new ObjectType("A$B") }, Constants.INVOKESPECIAL));
Now you can simply replace the String occurrences of "A$B$X" with "A$B$A" in the A$B$XCreator.java and AUseCreator.java, and then compile and run these classes.
The result will be a A$B$A.class file, and a AUse.class file that uses the A$B$A.class. Executing the AUse will print
Created A$B$A#15f5897 of class class A$B$A
I'm not sure whether this is considered as a "trick", or whether it still can be called "compiling" at all, but there is a way, at least. The key point is here, of course, that the fact that it did not compile is solely due to a limitation of the language, but there is no reason why this should not be representable in form of class files, regardless of how they are created.
You can't get it to compile, but more importantly, why would you need to?
What's wrong with:
public class A
{
public class B
{
public class InnerA
{
}
}
}
This seems like a design problem that you need to fix. If you can't rename it, consider anonymous inner classes. Or take some of those classes outside. Or just don't even use them.
It's a bit of a hack, but this compiles at my machine:
class A
{
public class B
{
public class Α
{
}
}
}
Try it. Literally: copy-past this thing ;)
SPOILER:
The name of the inner class is a capital letter alpha of the Greek alphabet. It's a Unicode character.
Depending on what you're after, the following might work for you:
public class A {
class B extends C {
}
public static void main(String[] args) {
new A().new B().new A();
}
}
class C {
class A {
{
System.out.println(getClass());
}
}
}
I thought I reasonably understood the use of packages but am experiencing an ostensibly trivial issue when attempting to use a method from an imported package.
I have three files in the following directory structure:
Tester.java
approach1\Approach.java
approach2\Approach.java
Their code is as follows:
Tester.java
import approach1.Approach;
public class Tester {
public static void main(String[] args)
{
approach1.Approach.sharedMethod("TEXT");
sharedMethod("TEXT");
}
}
approach1\Approach.java
package approach1;
public class Approach {
public static void sharedMethod(String approachText)
{
System.out.println("Approach Text: " + approachText);
}
}
approach2\Approach.java
package approach2;
public class Approach {
public static void sharedMethod(String approachText) { }
}
As you can likely guess, I'm trying to elicit different responses from the different approaches based on what package/class is imported. The problem I encounter is within Tester.java. The first, explicit line works fine whereas the second, imported line (sharedMethod("TEXT")) throws an error of "The method sharedMethod(String) is undefined for the type Tester". I don't understand as I have imported one of the packages, so the method should be visible.
Any clarification would be appreicated as I'm a Java newb. Thanks!
You could import your static method shareMethod like this
import static approach1.Approach.sharedMethod;
the standard kind of imports that you have used only import the classes - so everything within a class must be referenced using the class name. just use:
Approach.sharedMethod()
and now the compiler will be able to know which method to use all depending on which Approach class you have imported at the top.
Just to clarify:
import approach1.Approach;
public class Tester {
public static void main(String[] args)
{
Approach.sharedMethod("TEXT");
}
}
is different from
import approach2.Approach;
public class Tester {
public static void main(String[] args)
{
Approach.sharedMethod("TEXT");
}
}
You should only specify the class name and leave it to the package import statement at the top to determine which package to find the class/methods from.
You only need to explicitly mention the package in the main program body if there is a conflict in names or if you have not imported anything.
I have these two classes that I want to combine into a single file but i don't know how.
import java.util.LinkedList;
public class BFSolver{
public static boolean[][] didVisit;
public static LinkedList<Pair> expanded ;
public BFSolver() {
}
the other class looks something like this:
import java.util.LinkedList;
public class DFSolver{
public static boolean[][] didVisit;
public static LinkedList<Pair> expanded = new LinkedList<Pair>();
public DFSolver() {
}
when I put the import statments in one file
and the classes declerations in the same file, I got the error 'Unchecked' inside the main class.
You cannot put more than one public class in the same java file, except for inner classes.
If the relationship between them can be described as "BFSolver is a DFSolver", then you can use inheritance to get around the issue instead. Both of these classes would have to be in different files, since they're both public.
public class DFSolver {
protected boolean[][] didVisit;
protected List<Pair> expanded;
public DFSolver() {
// impl
}
// further impl
}
public class BFSolver extends DFSolver {
public BFSolver() {
// impl
}
}
The advantage here is that you don't have to copy or rewrite code to BFSolver; with the protected visibility modifier, you can access those fields just the same.
As others have stated, Java requires that only one public class can be in a single source file (unless the other is a static inner class), and the file name needs to match the class name. Other languages like Scala relax this requirement.
More interesting though is why you feel you want to. It looks instead like you either want to combine the classes into a single inheritance tree (though they have to still be different files) because they share behavior or combine common code into a utility class that both classes can delegate to.
But in any event, you're stuck with two files if you have two public non-static classes.
Ok, this might be kiddies question in java. We can't define two public classes in one file. But, in one of the examples from the book SCJP study guide, this example was mentioned:
public abstract class A{
public abstract void show(String data);
}
public class B extends A{
public void show(String data){
System.out.println("The string data is "+data);
}
public static void main(String [] args){
B b = new B();
b.show("Some sample string data");
}
}
When I copy pasted this into netbeans immediately compile error was thrown, that public class A should me mentioned in separate file. Is that example from SCJP styudy guide really wrong? Also in some of the mock test I found many questions having such pattern but in none of the options was a compiler error was mentioned. Getting worried here
yes, 2 top level public classes are not allowed in one file
Well, if one is being so picky: you can have multiple classes defined with a public modifier in the same file, that is, using the static nested(inner) class.
like this:
File -> Test.java
public class Test {
public static class SomeNestedClass {
}
}
Yes you can have two classes in the same file. You can have them by removing the public access modifier from both the class name, like shown below,
abstract class A{
public abstract void show(String data);
}
class B extends A{
public void show(String data){
System.out.println("The string data is "+data);
}
public static void main(String [] args){
B b = new B();
b.show("Some sample string data");
}
}
you can make 2 public classes in one file , inside a class that contains them .
it's also recommended to add "static" for them , if you do not need any reference to the container class .
You can put two public classes in one file, for example in the file Circle.java:
public class Test {
public static void main(String args[]) {
double cir = Circle.findCircumference(7.5);
System.out.print("Circumference of circle=" + cir);
}
}
public class Circle {
public static double findCircumference(double radius) {
return 2 * Math.PI * radius;
}
}
If you then run javac Circle.java, you will get an error:
Circle.java:1: error: class Test is public, should be declared in a file named Test.java
public class Test {
^
1 error
But if you run it with java Circle.java, then it will work.
Why? Probably because the java command, since java 11 (see here), can run also single source-file programs.
Imagine you could place two public classes in one file, then think about the work of the compiler: it has to build a .class file from your .java file that represents exactly one class (otherwise the .class ending wouldn't make any sense).
The way the JAVA Compiler works it will simply create a .class file with the name of your file and will search for the class with the name of the file in your given file – so it depends on your file name which class will be correctly compiled and which will not.
Long story short: no, you can't put two public classes in one file because the compiler wouldn't be able to handle that correctly.
(Edit: it of course is possible to define new classes INSIDE the one public class that has the same name as your file.)