包的导入会改变类的可见性吗?

发布于 2024-08-24 18:16:56 字数 359 浏览 5 评论 0原文

我刚刚了解到

一个类可以用 修饰符 public,在这种情况下 类对所有类可见 到处。如果一个类没有修饰符 (默认值,也称为 包私有),仅可见 在它自己的包中。

这是一个明确的声明。但这些信息干扰了我对包导入的理解(这很容易出错)。我认为导入包会使导入包中的类对导入类可见。

那么,它是如何运作的呢? 在导入包含公共类的包的情况下,公共类是否对任何地方的所有类都可见?或者说没有这个条件?包私有类怎么样?无论包含的包是否导入,它们都是不可见的?

额外: 在我看来,我得到了 2 个答案,它们被标记为好(已投票)并且彼此矛盾。

I jsut learned that

A class may be declared with the
modifier public, in which case that
class is visible to all classes
everywhere. If a class has no modifier
(the default, also known as
package-private), it is visible only
within its own package.

This is a clear statement. But this information interfere with my understanding of importing of packages (which easily can be wrong). I thought that importing a package I make classes from the imported package visible to the importing class.

So, how does it work? Are public classes visible to all classes everywhere under condition that the package containing the public class is imported? Or there is not such a condition? What about the package-private classes? They are invisible no mater if the containing package was imported or not?

ADDED:
It seems to me that I got 2 answers which are marked as good (up-voted) and which contradict eachother.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

何时共饮酒 2024-08-31 18:16:56

导入类不会以任何方式改变其可见性。将一个类导入到另一个类或多或少只是一种使源代码可读的方法,因此您不必始终放入完全限定的类。例如,此类

import java.util.*;

class ImportTests {
    private Collection collection;
}

编译为与此类相同的代码。

class ImportTests {
    private java.util.Collection collection;
}

第一个类中的 import 语句不会更改 Collection中的任何其他类的可见性。 >java.util 包它只是使 ImportTests 类可以引用 Collection 而无需完全限定名称。

Importing a class doesn't change its visibility in any way. Importing a class to another class is more or less just a way to make your source code readable so you don't have to put in fully qualified class all the time. For example this class

import java.util.*;

class ImportTests {
    private Collection collection;
}

compiles to the same code that this class would

class ImportTests {
    private java.util.Collection collection;
}

The import statement in the first class doesn't change the visibility of Collection or any other class inside the java.util package it just makes it so the ImportTests class can reference Collection without the fully qualified name.

梦在深巷 2024-08-31 18:16:56

您不需要导入路径或类来使其可见。

要使类或路径可见,您必须在编译或执行期间在类路径声明中指定。

“import”指令(C# 中的“using”指令)只是让我们变得懒惰。

如果您有课程,

why.does.the.sun.go.on.Shining.java,
rather.be.ahammer.thana.Nail.java,

您可以随时引用它们的完整路径,而无需导入它们:

public java.util.Hashtable<rather.be.ahammer.thana.Nail> bornFree(
 java.lang.String shiningKey,
 why.does.the.sun.go.on.Shining shiningPath){

 rather.be.ahammer.thana.Nail nailed =
   new rather.be.ahammer.thana.Nail(shiningPath);
 
 java.util.Hashtable<rather.be.ahammer.thana.Nail> nailedHash =
   new java.util.Hashtable<rather.be.ahammer.thana.Nail>();
 nailedHash.put(shiningKey, nailed);

 return nailedHash;
}

但是,懒惰是创造力的美德,我宁愿做

import java.util.Hashtable;
import why.does.the.sun.go.on.Shining.java;
import rather.be.ahammer.thana.Nail.java;

public Hashtable<Nail> bornFree(
 String shiningKey,
 Shining shiningPath){

 Nail nailed =
   new Nail(shiningPath);
 
 HashTable<Nail> nailedHash =
   new Hashtable<Nail>();
 nailedHash.put(shiningKey, nailed);

 return nailedHash;
}
 

哪个,您可能已经意识到了。

1 - 那么问题是,

如果有两个同名但命名空间不同的类,编译器将使用哪个类?

import java.util.Date;
import java.sql.Date;

编译器会发出错误消息 - 日期类冲突
并且你将无法成功编译。

因此,您必须导入其中一个并使用另一个及其完整路径。

在 C# 中,我们可以导入

using Dayhawk = hello.day.Hawk;
using Nitehawk = hello.nite.Hawk;

,这样我们就可以这样做,

DayHawk dhawk = new DayHawk(new NiteHawk());

但是,要么一如既往,java 独裁者要么害羞/自豪地允许自己允许 java 模仿微软,要么微软拥有这种形式的导入专利。

2 - 第二个问题是,

如果我们有一个类,

atlantic.salmon.are.trouts.String.java

那么你做了一个导入

import atlantic.salmon.are.trouts.String;

,当你声明

String salmon = new String();

将使用哪个字符串时? java.lang.String 还是 atlantic.salmon.are.trouts.String?

编译器将选择并遵守 import 语句并使用 atlantic.salmon.are.troouts.String。

3 - 第三个问题,

私有、受保护、公共可见性修饰符和默认可见性根本不要与导入指令混淆。除了使用相同的语言之外,别无他法。

  • 私有引用仅可见
    在同一个文件内。
  • 受保护的引用仅可见
    在相同的命名空间包中或
    通过扩展类。
  • 公共引用对所有人都可见。
  • 未声明的,即默认的,引用
    仅在相同的范围内可见
    命名空间包。

导入指令根本不会改变这些行为。

总之,

  • 进口指令仅适用于
    美德的延续
    懒惰。
  • 进口指令不适用于
    使类可见的目的或
    改变他们的可见性
    内容。
  • 类路径参数是为了使
    整个项目可见的类。
  • 注意其他可以改变行为
    Java 中的可见性修饰符
    汇编。

You do not need to import a path or a class to make it visible.

To make classes or paths visible, you have to specify at classpath declaration during compilation or execution.

"import" directive ("using" directive in C#) merely helps us to be lazy.

If you have classes

why.does.the.sun.go.on.Shining.java,
rather.be.ahammer.thana.Nail.java,

you could always refer them with their full paths without importing them:

public java.util.Hashtable<rather.be.ahammer.thana.Nail> bornFree(
 java.lang.String shiningKey,
 why.does.the.sun.go.on.Shining shiningPath){

 rather.be.ahammer.thana.Nail nailed =
   new rather.be.ahammer.thana.Nail(shiningPath);
 
 java.util.Hashtable<rather.be.ahammer.thana.Nail> nailedHash =
   new java.util.Hashtable<rather.be.ahammer.thana.Nail>();
 nailedHash.put(shiningKey, nailed);

 return nailedHash;
}

However, laziness being the virtue of creativity, I would rather do

import java.util.Hashtable;
import why.does.the.sun.go.on.Shining.java;
import rather.be.ahammer.thana.Nail.java;

public Hashtable<Nail> bornFree(
 String shiningKey,
 Shining shiningPath){

 Nail nailed =
   new Nail(shiningPath);
 
 HashTable<Nail> nailedHash =
   new Hashtable<Nail>();
 nailedHash.put(shiningKey, nailed);

 return nailedHash;
}
 

Which, you probably have already realised.

1 - The question would then be,

if there are two classes of the same name but different namespace, which would be used by the compiler?

import java.util.Date;
import java.sql.Date;

The compiler would complain with error message - conflicting classes for Date
and you would not be able to compile successfully.

So you have to import one of them and use the other with its full path.

In C# we could import

using Dayhawk = hello.day.Hawk;
using Nitehawk = hello.nite.Hawk;

So that we could do,

DayHawk dhawk = new DayHawk(new NiteHawk());

However, either as always, the java authoritarians are either to shy/proud to allow themselves to allow java immitate Microsoft or that Microsoft has a patent on such form of import.

2 - The second question would be,

if we had a class

atlantic.salmon.are.trouts.String.java

Then you did an import

import atlantic.salmon.are.trouts.String;

And when you declare

String salmon = new String();

which String would be used? java.lang.String or atlantic.salmon.are.trouts.String?

The compiler would pick and obey the import statement and use atlantic.salmon.are.trouts.String.

3 - the third issue,

private, protected, public visibility modifiers and default visibility are not to be confused with the import directive at all. Nothing to do except being in the same language.

  • private references are visible only
    within the same file.
  • protected references are visible only
    within the same namespace packages or
    by an extension class.
  • public references are visible to all.
  • Undeclared, i.e. default, references
    are visible only within the same
    namespace packages.

Import directive does not change these behaviours at all.

In conclusion,

  • The import directive is merely for
    the continuance of the virtue of
    laziness.
  • The import directive is not for the
    purpose of making classes visible or
    changing the visibility of their
    contents.
  • The classpath argument is for making
    classes visible to the whole project.
  • Noting else can change the behaviour
    of visibility modifiers in a Java
    compilation.
美人如玉 2024-08-31 18:16:56

我有两个包A和C。A中有一个名为Random的类。我这里的代码编译得很好,随机数来自 A 而不是来自 java.util。 java.util 导入在 Eclipse 中向我发出警告,提示导入未使用。

package C;

import A.Random;
import java.util.*;

public class C
{
public static void main(String[] args)
    {
        Random b = new Random();
    }
}

这是隐藏类的另一个例子。

package C;
import java.util.*;
public class C
{
public static void main(String[] args)
    {
        Random b = new Random();
        System.out.println(b.nextDouble());
    }
}

这是我的随机课程。

package C;
import java.util.Scanner;

public class Random 
{
private static final long serialVersionUID = 2632389638401709212L;

Scanner s;

public Random()
    {
        super();
        s = new Scanner(System.in);

    }
public double nextDouble()
    {

        System.out.println("Enter your own random number");
        return Double.parseDouble(s.nextLine());            
    }
}

当我运行 C main 方法时,我得到......

Enter your own random number
1
1.0

I have two packages A and C. A has a class named Random in it. My code here compiles fine, and the random is from A and not from java.util. The java.util import gives me a warning in eclipse that the import is unused.

package C;

import A.Random;
import java.util.*;

public class C
{
public static void main(String[] args)
    {
        Random b = new Random();
    }
}

Here is another example of the hiding of classes.

package C;
import java.util.*;
public class C
{
public static void main(String[] args)
    {
        Random b = new Random();
        System.out.println(b.nextDouble());
    }
}

Here is my Random class.

package C;
import java.util.Scanner;

public class Random 
{
private static final long serialVersionUID = 2632389638401709212L;

Scanner s;

public Random()
    {
        super();
        s = new Scanner(System.in);

    }
public double nextDouble()
    {

        System.out.println("Enter your own random number");
        return Double.parseDouble(s.nextLine());            
    }
}

When I run the C main method I get...

Enter your own random number
1
1.0
许久 2024-08-31 18:16:56

如果您想使用 B 类 中的 A 类,并且 B 类 位于同一个类A,您必须导入类B,即使类B是<代码>公共。

如果不需要导入公共类,就无法声明两个同名的类。

If you want to use class A from class B, and class B is not in the same package with class A, you must import class B, even if the class B is public.

If public classes didn't need to be imported, there could be no way of declaring two classes with the same name.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文