why is it possible to create String.java? - java

Just trying to understand why I am able to create String.java file and it is compiled without any errors. As far as I know, the classloader chain will go to Bootstrap classloader and it has already loaded Sting.class.
Could you pls help me in understanding?

A class is not identified by just its name, but by its fully-qualified name, which is the name of the package followed by the name of the class.
If you create your own String class in some package com.myapp, then its fully-qualified name will be com.myapp.String. It doesn't conflict with the standard String class, which has the fully-qualified name java.lang.String.
Of course, it's going to be very confusing when you do this, especially because classes in the package java.lang are imported by default. Therefore, in practice you should never write your own class String, or name any of your own classes the same as classes from the standard library (especially standard classes from the package java.lang).

As highlighted by Jesper, the uniqueness of a class is determined by its fully qualified name i.e., package..
Try importing both the String classes in another class, and you will observe the difference when you will try to use it.
import java.lang.String;
import com.myclass.String;
Now, for resolving the ambiguity, you need to refer a class by its fully qualified name.

Related

What to do if 2 classes have the same package statement

I'm running into a problem where 2 classes from 2 different packages (owned by the same group) have the same name and package statement
Package 1
package com.placeholder.constants.Constants
public class Constants{}
Package 2
package com.placeholder.constants.Constants
public class Constants{}
If I'm working on Package 1 but want to reference this Constants class in Package 2, is this even possible?
Cannot duplicate class name within same package
where 2 classes from 2 different package
But they are not two different packages. You’ve used the same package name for both.
want to reference this Constants class in Package 2
Use either:
A different package name
A different name for your new class
You cannot define two classes with the same name in the same package, for obvious reasons.
The purpose of packages in Java is to create a namespace. Your duplicate class name violates that namespace.
Design problems
package com.placeholder.constants.Constants
That is not a proper package name. You’ve mixed the class name into the package name. The package should be package com.placeholder.constants.
This cross-naming problem of yours raises the possibility that you have a less than optimal class design. You might want to pause a moment to look at the bigger picture.
And if you have that many constants to name, I wonder if some of those should really be enum types. See tutorial by Oracle. Tip: In Java 16 and later, enums can be defined locally, within an a method — a new alternative to being defined as a nested class or defined as a separate class.
You are facing a name conflict. If possible, try to enter the full name of the package.class_location

"The import [...] conflicts with a type defined in the same file" error [java]

I'm importing a package (in my case, mongodb.DB) into a java file with an identically named class.
In python, I know I can import a module as another name to avoid conflicts. How does Java solve this problem?
It's not feasible to change the name of the class I'm working in.
You say you are "importing a package..." - do you mean you are importing all classes in a package, like "a.b.c.*"? If so, the answer might be to import only those classes you need, not the entire package.
There is no way to import a class as another class.
Hopefully you don't really mean "identically named" as in both of them having the same fully-qualified name. If that's the case, you're screwed, I don't know anything you can do. Hopefully you just mean that the class name is the same in two different packages.
You can extend a class with your own class, and use your new class in the place of the one extended. In other words, if you're importing the class D as in a.b.c.D, and there is another D class, you could extend the first of them (class Z extends a.b.c.D), and then refer to it as Z instead of D. You might need to provide constructors for Z that match ones in D, but no code should be required other than that.
And the fully-qualified names of the classes will always work.
You can use the fully qualified name "mongodb.DB" instead of just the class name.

Java import statement syntax

This is a simple question, but I am really bugged by it. I was trying to find a duplicate, and googled it, but I was more surprised when I couldn't find a satisfying answer.
import java.util.Scanner;
In this statement .Scanner is the class,
.util is the name of the package
What is java or javax or whatever would stand before the first period in general?
UPDATE:
I also found this picture:
http://www.javatpoint.com/package
Is it true?
Per the JLS 7.1:
The members of a package are its subpackages and all the top level class types (§7.6, §8) and top level interface types (§9) declared in all the compilation units (§7.3) of the package.
For example, in the Java SE platform API:
The package java has subpackages awt, applet, io, lang, net, and util, but no compilation units.
The package java.awt has a subpackage named image, as well as a number of compilation units containing declarations of class and interface types.
If the fully qualified name (§6.7) of a package is P, and Q is a subpackage of P, then P.Q is the fully qualified name of the subpackage, and furthermore denotes a package.
So you can glean from that:
java is a package with no classes, only subpackages.
util is a subpackage of java whose fully qualified name is java.util.
util does not denote a package, java.util does.
"I also found this picture: ... Is it true?"
Yes, util is a subpackage of java. However, util is not a package. java.util is a package.
You can think of packages as a directory structure, if you wish, where each subpackage is a folder inside its outer package. So there would be a "folder" java and, inside that, another "folder" util. A package is denoted by its fully qualified name ("full path") so java is a package and java/util is a package. /util is not a package. But packages represented by a directory structure is not a spec. It is only a common implementation. It is up to the host system to decide how packages are stored (JLS 7.2).
Classes in Java are identified by a fully qualified name consisting in a concatenation of the package of the class and the name of the class (and any outer classes, if any). In general, in an import statement like:
import foo.bar.baz.MyClass;
everything except the last dot-separated field is the package name (foo.bar.baz) and the last field is the class name (MyClass). In your example, java.util is the package name and Scanner is the class name.
The process is actually a bit more complicated, as inner/nested classes and interfaces may be involved, but you get the idea.
import java.util.Scanner says.
Look in the package java.
Within that look in the package util.
Within that find the class Scanner.
Now whenever we use the name of a class/etc within this java file (for example Scanner s = new Scanner()) then the class found by the import will be used.
Alternatively you could not do the import and do java.util.Scanner s = new java.util.Scanner() but you can see how that would quickly become unwieldy, especially if you use it in a lot of places within your file. Imports are just a handy way to reduce repeatedly specifying which version of the Scanner class you mean when you refer to Scanner.
A few points:
the package name is java.util, not util. "java" is just part of the package name.
package names are any series of valid java identifiers separated by dots, AbC123.XYZ.foo is a valid package name
package may be omitted. If absent, the class is in the root directory of the project (I once worked on a project in production that had no packages! Everything was in one directory... Yikes!)
by convention, packages starting with java are part of the JDK (plus extensions). There is nothing in the language that specifies this or enforces it
java and util are names of nested packages. java.util is a path to final package.
They are directories inside rt.jar file.
rt.jar file is a zip archive, you can view it with 7-zip program.
Scanner is a Scanner.class file inside java/util directory inside rt.jar
import java.util.Scanner directive just allows you to use Scanner class name in code without specifying full path to it.
import java.util.* directive allows you to use ALL class names in java.util without a path.
import static java.util.Scanner.* directive allows you to use ALL static members inside Scanner, without a paths. But there are none.
List of all packages in JRE are here: http://docs.oracle.com/javase/7/docs/api/overview-summary.html
1) java is a package. (also represents a folder in file system).
It is directly in the classpath, so it is referenced by your program as 'java'. (subfolder in java folder)
2) util is a package inside java package (hence referenced as 'java.util').
3) Scanner is a class inside util package (hence 'java.util.Scanner')
You can have as many nested packages as you want like 'mypackage1.mypackage2.mypackage3. ...' and so on, as long as mypackage1 is in the classpath.
Hope this helps
the import statement represent a hierarchy
import java.util.Scanner;
java is the package
util is the subpackage (inside java)
Scanner is the class (inside util)
import java.util.*;
The class name could be subtituited with an asterisk,
and that means import all classes in the mentioned subpackage.

How to resolve class name to fully qualified in Java?

Is there any way in Java to resolve simple class name (e.g. String) to fully qualified one (e.g. java.lang.String) or better yet to Class directly? The only way that comes to my mind is to parse file for imports and figure out from classpath jars. Sure there must be a better way.
There is no way to do this in a general way, since the same class name can be used in several packages, for example "Date" can be java.util.Date or java.sql.Date. Unless you can somehow limit the search area, this isn't even theoretically possible.
Also, one must wonder what use case would require you to get a Class from an unqualified class name.
Java compiler determines fully qualified names class names by trying to find classes on the class path with different combination of simple class names in source file and package names in import statements. Compiled classes (.class) always get fully qualified names.
import java.util.Date;
public class Test {
String str;
Date date;
...
compiles to Test.class
public class Test {
Ljava/lang/String; str
Ljava/util/Date; date
...

Put the class containing the main method into a sub-package

I am making a project named TruckingCompany, there is a package name truckingCompany, and three sub-packages: utilities, means and objects.
Now I have put the class containing the main method into the utilities sub-package.
Is this correct? Should I put it into the truckingCompany package ( in no sub-package)?
So the generic question is: if there is a package, and some sub-package, and the main method uses classes from all sub-packages, is correct to put the class containing it in a sub-package?
PS: Let me know if the question is not clear.
Yeah, you can just put it in truckingCompany. After all, it is your application's entry point.
As a baseline, from what I've seen so far a good practice is to put the class containing the main method at the top-level package.
In your case, I'd put your class under the package truckingCompany and not in a sub-package.
You should put in truckingCompany but it will work doesn't matter where ever you put it
It is absolutely irrelevant where you put your class. More specifically, a package has no special relation to its subpackages. The packages are basically a flat namespace of package names. I would also like to add that there are some conventions to be followed with package names:
You are supposed to use all lowercase letters;
the package name should be derived from an internet domain name that you own: com.truckingcompany.stuff.morestuff.

Categories

Resources