Same class name in different packages - java

Can same class exist in multiple packages?
In other words, can I have Foo.java class in com.test.package1 and com.test.package2?
Update
Now I copied class from package 1 and placed in to package 2 and now I am creating an instance of that class, I want this instance to point to class present in package 1 but currently it points to package1 path, how can i modify it?
Oh so I cannot do something like:
Foo = new Foo() // pointing to Foo class in package 1
Foo = new Foo() // pointing to Foo class in package 2

Yes, you can have two classes with the same name in multiple packages. However, you can't import both classes in the same file using two import statements. You'll have to fully qualify one of the class names if you really need to reference both of them.
Example: Suppose you have
pkg1/SomeClass.java
package pkg1;
public class SomeClass {
}
pkg2/SomeClass.java
package pkg2;
public class SomeClass {
}
and Main.java
import pkg1.SomeClass; // This will...
import pkg2.SomeClass; // ...fail
public class Main {
public static void main(String args[]) {
new SomeClass();
}
}
If you try to compile, you'll get:
$ javac Main.java
Main.java:2: pkg1.SomeClass is already defined in a single-type import
import pkg2.SomeClass;
^
1 error
This however does compile:
import pkg1.SomeClass;
public class Main {
public static void main(String args[]) {
new SomeClass();
new pkg2.SomeClass(); // <-- not imported.
}
}

Sure can but you'll need to distinguish which one you want when calling them in other packages if both are included within a source file.
Response to Comment:
com.test.package1.Foo myFoo = new com.test.package1.Foo();
com.test.package2.Foo myOtherFoo = new com.test.package2.Foo();

i was taken to this page by google when i had the error a type with the same simple name is already defined by the single-type-import. i fixed this error (AFTER A VERY LONG TIME) by realising the line import com.sun.org.apache.xerces.internal.impl.dv.util.Base64; had snuck into the very top of my imports whilst i had the line import org.apache.commons.codec.binary.Base64; at the bottom of my imports.

So I was looking for a smarter solution than just using fully qualified names on one or both of the implemented classes.
If you create a private class, and extend your class, you are free to use the class, without writing the full package name each time.
Package 1
namespace namespace1.Logger
{
public class Log
{
public void Foo1(){}
}
}
Package 2
namespace namespace2.Logger
{
public class Log
{
public void Foo2(){}
}
}
My class implementation
//using namespace1.Logger;
//using namespace2.Logger;
namespace MyProject
{
public class MyClass
{
public MyClass()
{
LoggerA a = new LoggerA();
LoggerB b = new LoggerB();
a.Foo1();
b.Foo2();
}
private class LoggerA : namespace1.Logger.Log { }
private class LoggerB : namespace2.Logger.Log { }
}
}

Related

Is there any way to reduce the length of static variable from another class?

I have a public class Helper in another file that has a few public static variables declared. I'm wondering if it's possible to shorten the variable name so that I don't have to consistently use Helper.<variable_name> everywhere. It would be ideal if I could just use the variable name without the Helper prefix.
Use
import static a.b.c.Helper.<variable_name>;
where a.b.c is the package which contains the Helper class.
You can use a static import:
// Class1.java
package test;
import static test.Class2.static_var;
public Class1 {
public static void main(String[] args) {
System.out.println(static_var); // not Class2.static_var
}
}
// Class2.java
package test;
public class Class2 {
public static String static_var = "Hello";
}
Output from java test.Class1:
Hello
Wildcard imports also work:
import static test.Class2.*;
Note that you must specify the full package name in the static import declaration. It is not sufficient to import test.Class2; and then import Class2.*;.

Confusion with Java packages

So I thought I understood packages, but turns out I don't.
Classes inside a package: I have this folder structure: mypackage/mysubpackage. Inside mysubpackage folder I have 2 classes:
package mypackage.mysubpackage;
public class Class1 {...}
and
package mypackage.mysubpackage;
public class Class2 {...}
However, when I compile Class1 (which uses methods from Class2) using javac Class1.java inside the directory mypackage/mysubpackage, it can't see Class2:
Class1.java: error: cannot find symbol
Class2 c = new Class2();
^
symbol: class Class2
location: class Class1
It works fine if I run javac Class1.java in the directory that contains mypackage/mysubpackage. Shouldn't the compilation work inside mysubpackage folder?
Classes in another package: Now, I have another class with methods that I want to be accesible to all the subpackages, so I create a final Commons.java inside mypackage/commons:
package mypackage.commons;
public final class Commons {
public static double method() {...}
...
}
And then I update Class2 importing that class so that I can use its methods inside the class:
package mypackage.mysubpackage;
import mypackage.commons.*;
public class Class2 {...}
Now it doesn't find the method I defined in the final class:
./mypackage/mysubpackage/Class2.java: error: cannot find symbol
double var = method();
^
symbol: method method()
location: class Class2
Shouldn't if find it? I think I'm importing it correctly, the methods are static and the class is final. Why doesn't it recognize it?
Cheers!
Looks like your problem is with where you set your working directory when you launch the Java compiler from the command line.
I would recommend that you pick up an integrated development environment -- Eclipse is a good one. Using the IDE you run into no such problems. Here are the classes I just created in Eclipse, which compile correclty.
Commons
package com.example.packagecommons;
public class Commons {
public static double method() {
return 0;}
}
Class1
package com.example.packages;
public class Class1 {
private Class2 c2;
public Class1() {
c2 = new Class2();
}
}
Class2
package com.example.packages;
import com.example.packagecommons.Commons;
public class Class2 {
private double initialValue;
public Class2() {
initialValue = Commons.method();
}
public double getValue() {
return initialValue;
}
}
Suppose your two classes Demo01 and Demo03 are in package pack1.subpack and your Demo02 is in pack2
So the hierarchy is like
someDrive/pack1/subpack/Demo01
someDrive/pack1/subpack/Demo03
someDrive/pack2/Demo02
someDrive/pack1/common/Demo04
where Demo01 is
package pack1.subpack;
import pack2.Demo02; // need to add this if calling class of different package
import pack1.common.Demo04; // if you are going to use Demo04 class in Demo01 class
public class Demo01 {
public void run() {
System.out.println("--running Demo01-");
}
public static void main(String[] args){
Demo01 demo01 = new Demo01();
demo01.run();
Demo02 demo02 = new Demo02();
demo02.run();
Demo03 demo03 = new Demo03();
demo03.run();
Demo04.run();
}
}
Demo02 is
package pack2;
public class Demo02 {
public void run() {
System.out.println("--running Demo02--");
}
}
Demo03 is
package pack1.subpack;
public class Demo03 {
public void run() {
System.out.println("--running Demo03--");
}
}
Demo04 is
package pack1.common;
public final class Demo04 {
public void run() {
System.out.println("--running Demo04--");
}
}
Then just compile it using javac pack1/subpack/Demo01.java
and execute it using java pack1/subpack.Demo01
I know this thread is old but I'd like to clarify things so as to help future viewers.
Your first question basically is, how does the Java run-time system know where to look for packages that you create? Remember these 3 rules (one of them must apply):
Your main package must be in a subdirectory of the current working directory to be found.
You can specify a directory path or paths by setting the CLASSPATH environmental variable.
You can use the -classpath option with java and javac to specify the path to your classes when you are executing your code via the terminal/cmd.
To answer your first question, you are executing your code from mypackage/mysubpackage. For Java run-time to recognise Class2, you must execute from mypackage.
Coming to the second question, when you import all the contents of a package using *, you need to refer to static class members by explicitly writing the class name before them, as Java does not know which class in the package you are referring to. Hence, in your code, you must write
Commons.method() instead of just method(). If you do not want to prefix the name of the class time and again, you can explicitly import the specific class you want. In your case, this would be mypackage.commons.Commons. Then you can call method() directly (provided it is static).
sh$ cd package/subpackage
sh$ javac Class1.java
Will lead to an error as the compiler will try to locate Class2 in the package/subpackage subdirectory of the current directory.
You have to compile that way:
sh$ javac package/subpackage/Class1.java
Here is a complete working example:
sh$ cat pkg/subpackage/Class1.java
package pkg.subpackage;
import pkg.commons.Class2;
public class Class1 {
public static void main(String args[]) {
Class2.doSomething();
}
}
sh$ cat pkg/commons/Class2.java
package pkg.commons;
public class Class2 {
public static void doSomething() {
System.out.println("hello");
}
}
sh$ javac pkg/subpackage/Class1.java
sh$ java pkg.subpackage.Class1
hello

override the new package with the old one

Considering a java application with a embedded X impl/jar file, for example com.test package.
and we cannot change and modify the jar file.
Now suppose I have a X1.jar file which is modified version of exist X(com.test) package.
Question:
Is it possible to override the X1.jar implementation with embedded(exist) implementation just before the library gets loaded? and again, assume we cannot change the package anyway.
I'd like that to redirect all the types under com.test package to the new one.
Thanks in advance.
As per m0skit0's suggestion:
Orig class:
package example.x
public class SomeClass
{
public SomeClass(String neededVar)
{...}
public String someMethod(String someVar)
{
// original implementation
}
}
Custom class:
import example.x.SomeClass
public class MySomeClass extends SomeClass
{
public MySomeClass(String neededVar)
{
super(neededVar);
// anything else
}
#Override
public String someMethod(String someVar)
{
// implement differently
super.someMethod(someVar);
// or add to it
}
}

Java : The import collides with another import statement

I have imported an Existing Java Application into my Workspace .
I see that , a class with same name is present in different packages with in the Application.
For example a class named "Status.java" is present with in
com.tata.model.common.Status;
com.bayer.frontlayer.dao.Status;
When I tried to use both of them within a class, for example as shown below
import com.tata.model.common.Status;
import com.bayer.frontlayer.dao.Status;
public class Adapter
{
}
It started giving an error in Eclipse stating
The import com.bayer.frontlayer.dao.Status collides with another import statement
Is there anyway to solve this without changing the name of the classes??
Thank you.
You can use them explicitly without importing them, so the included package name differentiates between the two:
//No imports required!
public class Adapter
{
private com.tata.model.common.Status x;
private com.bayer.frontlayer.dao.Status y;
}
You can import just one of the classes and use the fully qualified name for the other one.
e.g.
import com.tata.model.common.Status;
//import com.bayer.frontlayer.dao.Status;
class SomeClass{
void someMethod(){
new Status(); // com.tata.model.common.Status
new com.bayer.frontlayer.dao.Status(); //com.bayer.frontlayer.dao.Status
}
}
Though I think it would be less confusing in your case if you just used the fully-qualified names for both classes.
Directly apply full Class Names wherever applicable. Eg-
public class SomeClass {
public someMethod() {
com.myapp.someotherpackage.Status = "something";
com.some.other.package.Status = "otherthing";
if(com.myapp.someotherpackage.Status == com.some.other.package.Status) {
}
....
}
}

Accessing non top-level class without a top level class in Java

I have a Java file TestThis.java like the following:
class A
{
public void foo()
{
System.out.println("Executing foo");
}
}
class B
{
public void bar()
{
System.out.println("Executing bar");
}
}
The above code file is compiling fine without any warnings/errors. Is there any way I could access any of class A or B without a top level class from any other external class?
If no then why does Java even permit compiling of such files without a top-level class?
As usual (for example, accessing from the Test.java):
public class Test {
public static void main(String... args) {
A a = new A();
a.foo();
B b = new B();
b.bar();
}
}
The rule here is that you could not have more than one public class in the source file. If you have one, the filename must match this public class name. Otherwise (your case), you can name your file as you wish. Other, non-public classes, will be package-visible and you can access them as usual.
Any other class in the same package can access A and B; in this case the null package is being used since no package statement is present for the source file.

Categories