2

I was watching a lecture on Java when I caught myself not specifying package in Java file.

They lecturer was using Java 11 on Netbeans, and I Java 1.8 on IDEA. By default Netbeans created him a package, and the main java file has package specified.

But on IDEA, I noticed that I don't need to specify package name, when creating .java file inside src\main\java folder. And I have a question why?

  1. Why is src\main\java a folder, and not a package?
  2. What is the difference between a folder and a package?
  3. In Python, they create __init__.py file inside of a package, in order to make Python interpreter see the package. How is it working in Java, if there is no __init__ file? How does Java understand that this is a folder, and that is a package?
  4. Why does Java need to introduce and separate folder and package terms?
  • Does this answer your question? [Difference between Package and Directory in Java](https://stackoverflow.com/questions/12652899/difference-between-package-and-directory-in-java) – OldProgrammer Mar 30 '22 at 18:16
  • Plus some foundational Know-how about packages and classpath: https://www3.ntu.edu.sg/home/ehchua/programming/java/J9c_PackageClasspath.html – Aydin K. Mar 30 '22 at 18:17
  • @OldProgrammer Not really. –  Mar 30 '22 at 18:23
  • @AydinK. "A package is a collection of related Java entities". Folder is not? I can create multiple Java files inside src\main\java, which is considered a folder. Not a package. –  Mar 30 '22 at 18:24
  • @OldProgrammer They say what is a package, and why you should use it, but they don't say what is the difference (my 2 question). My 1, 3 and 4 questions are not answered either. –  Mar 30 '22 at 18:26
  • It is both. A package is a representation of a folder structure. – Aydin K. Mar 30 '22 at 18:54
  • To answer your question: if you put Java files into the src\main\java folder and this is the root (think of entry point) than those files are automatically in the default package (""). – Aydin K. Mar 30 '22 at 19:31
  • `src/main/java` means **nothing** in Java itself, it just a convention established by Maven (and also used by Gradle) where to put your files. You can also have `src/test/java` for your tests, and `src/main/kotlin` for Kotlin source files (and, at least in theory, you could also have `src/main/python` if your project contains Python, etc). What is inside that directory then follows the layout for that specific language (e.g. for Java org/example/SomeClass.java for the class `org.example.SomeClass`). – Mark Rotteveel Apr 01 '22 at 12:04

2 Answers2

2

Why is src\main\java a folder, and not a package?

Which folders become packages depends on where the "root" is defined. In IDEA, src/java/main is the root. Any folders inside of that are mapped to packages. If for example, you create a folder src/java/main/foo and create a Foo.java in that folder, you will have a class named Foo in a package named foo.

What is the difference between a folder and a package?

A package is a way to group related Java classes. Sometimes a package is implemented as a folder in your file system. Sometimes it is something else. (See below.)

Why does Java need to introduce and separate folder and package terms?

One reason to differentiate between folders and packages is that some packages aren't folders. For example, you can download a .jar file from the Internet which contains a Java library. The library inside that .jar file defines packages and classes that you can use in your own code, but there are no folders for the packages.

The reason for a new term "package" is to create an abstraction that isn't tied to the folders in your local file system.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • What is root? A folder? A package? A package that is "A Father Of All"? –  Mar 30 '22 at 19:20
  • What he names root is what I called the baseline or the classpath. – Queeg Mar 30 '22 at 19:28
  • @Freddy By "root", I mean the base folder that contains subfolders which map to Java packages. The path to get to that base folder is ignored for the purposes of naming packages. – Code-Apprentice Mar 30 '22 at 19:29
  • @Freddy I've also added some more details to answer more of your question. – Code-Apprentice Mar 30 '22 at 19:35
  • The other guy too said that there can be one folder and different packages. But he could not prove that. Because he cannot eventually run from cmd those. Means, answer is unproven, means the question is still open. Maybe you can run one folder, different packages? –  Mar 31 '22 at 15:03
  • Suppose I have Test.java and Test2.java in one folder. I add "package testpack;" inside Test2.java. Test.java has main method, which calles a method from Test2.java. I could achive their compiling via "javac *.java" command. How do I run Test.java? –  Mar 31 '22 at 15:06
  • I already tried mutiple combinations, but the problem is, No class def found testpack/Test2. –  Mar 31 '22 at 15:07
  • @Freddy When you declare `package testpack;`, that `Test2.java` file must be in a subfolder named `testpack`. – Code-Apprentice Mar 31 '22 at 15:45
  • "One reason to differentiate between folders and packages is that some packages aren't folders" –  Mar 31 '22 at 16:05
  • @Freddy Yes, I know what I said. If you continue reading, I gave an example. – Code-Apprentice Mar 31 '22 at 16:13
  • Sooo, now it turns out that packages ARE folders. –  Mar 31 '22 at 16:13
  • @Freddy Nope. It turns out **in this specific case** you must make a folder. – Code-Apprentice Mar 31 '22 at 16:14
  • @Freddy To me more specific, some packages are folders and some aren't. – Code-Apprentice Mar 31 '22 at 16:14
  • Which of them aren't? –  Mar 31 '22 at 16:15
  • @Freddy I gave an example in my answer. – Code-Apprentice Mar 31 '22 at 16:15
  • Jar is an archive, which actually has folders inside of it. –  Mar 31 '22 at 16:16
  • @Freddy Kind of, yes. But not really. The "folders" in a JAR archive aren't exactly the same as the folders on your harddrive. – Code-Apprentice Mar 31 '22 at 16:17
0

The difference between a package and a folder is not directly evident unless you define your classpath yourself.

All directories and all zip files you add to the classpath create a baseline. Such as the .../src/main/java folder. Underneath that baseline you can still create folders with classes. But for Java these will be treated as packages.

So in the filesystem packages are resembled by folders. In zip files (and jar files are nothing but zip files with some metadata) there are no filesystem folders but still something folder-like that can be extracted into filesystem folders. And it is thinkable that people would write even other Classloaders that do not just do simple filesystem or zipfile access. They can do virtually anything which could even range to loading classes from different websites - just based on their package names.

As soon as a class is not in the default package (in a folder on the classpath directly) it needs the package name declared in it's source code. And that is what you spotted. Well done!

Summary: .../src/main/javais the default package (that does not need to be specified) because that folder is added to the classpath when the JVM executes. Any classes in subfolders need their package defined.

A small detail: The classpath is set for the compiled classes, not the java source files. You could keep all java sources in the same directory and just declare by package into which 'folder' the compiled output should go. But it is good practice to organize the source files in the same structure that will be emitted by the compiler. Any IDE will help you maintain that structure.

Queeg
  • 7,748
  • 1
  • 16
  • 42
  • Okay, so java is a package itself. But what do you mean by "and just declare by package into which 'folder' the compiled output should go. "? When I create Test.java inside src\main\java package, and write in the beginning of the file "package testpack;" IDEA tells me: "Package name 'testpack' does not correspond to the classpath "" –  Mar 30 '22 at 19:24
  • True, the IDE helps you to maintain a consistent structure. Try the same without an IDE. You have the source files, then try to compile them using plain javac. – Queeg Mar 30 '22 at 19:27
  • I did, but now I can't run them))). I did >javac *.java. Then I did >java -cp ".\;testpack\Test2.class" Test. No Class Def found/ –  Mar 30 '22 at 20:32
  • Classes Test and Test2 are in the same folder. Test2 has "package testpack;" line in it. Test has main method. –  Mar 30 '22 at 20:34
  • Hmm. When I last tried it the class files would get written to different folders (depending on the package they had). Maybe that behaviour has dropped. Nevertheless, you should run them like `java -cp . testpack.Test2` – Queeg Mar 30 '22 at 22:28
  • Still doesn't work. I still need to run Test, which has main method. I do java -cp .testpack.Test2 Test, and it says Could not find or load main class Test –  Mar 31 '22 at 06:16
  • The behaviour must have changed then, I remember it otherewise. But have not worked without an IDE for quite some time. Do not care. I think you have a clearer picture about the classpath now. Go back to the IDE, create packages and compile, then run from command line. It will be better. – Queeg Mar 31 '22 at 13:38
  • Maybe I was gonna write my own IDE? :D Or my own Maven alternative? :D –  Mar 31 '22 at 14:57
  • Go for it. If you create something that is better than the existing solutions I am likely to use it. :-) – Queeg Mar 31 '22 at 21:11