Java中有类似Internal类的东西吗?

发布于 2024-11-07 00:34:04 字数 72 浏览 3 评论 0原文

在 C# 中,您可以将类标记为 internal,以便只能从同一包内访问它。 Java中有类似的东西吗?

In C# you can mark a class as internal so that it is only accessible from within the same package. Is there anything similar in Java?

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

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

发布评论

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

评论(8

笛声青案梦长安 2024-11-14 00:34:04

您可以通过在类声明中省略安全修饰符(public、private)来创建包私有类。

package com.sample;

class MyPackagePrivateClass
{
    ...
}

You can create package-private classes by omitting the security modifier (public, private) from the class's declaration.

package com.sample;

class MyPackagePrivateClass
{
    ...
}
饮惑 2024-11-14 00:34:04

这个问题之前有一个公认的答案,但我认为对于来自 .Net 的 java 新手来说,答案并不完全清楚。

java 是否有与 C# 中的内部修饰符完全相同的东西?简短的回答是否定的(但你可以通过一些方式实现它,我会告诉你)!

C#中的internal实际上是一个“程序集私有”修饰符。什么是集会?

程序集是项目的任何产品(C# 中的 DLL 或 EXE - java 中的等效项可以是 JAR 文件),

java 中的内部没有任何精确等效项。 Bryan Kyle 回答并接受的实际上是“包私有”(java 中的包相当于 C# 中的命名空间),但有些回答是获得相同结果的最接近的方法。

但如何获得与内部完全相同的结果? java 不能有解决方案吗?答案是肯定的。

确实有。但不能使用修饰符。
实际上,最好的方法是在包装中隐藏秘密。打包的最佳实践是根据类的关系而不是类型来打包类。

我们中的许多人都使用名为“Models”或“Presenters”的包,并将所有模型或演示者放入其中。虽然这是错误的。包应该像“Book”包含“BookModel.java”,“BookPresenter.java”,.....

这样你可以通过省略修饰符使它们成为包私有,并且没有任何问题,因为你可以在任何地方访问它们类需要你的包私有类,因为你有很好的打包实践。

this Question has an accepted answer before but I think the answer is not fully clear for some one who is new in java coming from .Net.

Does java have some exact equivalent for internal modifier in C# ? short answer is NO (but you can achieve it some how and i will tell)!!

internal in C# is actually an "assembly-private" modifier. what is an assembly ?

Assembly is any product of your project (DLL or EXE in C# - equivalent in java can be a JAR file)

there is not any exact equivalent for internal in java. and what has been answered by Bryan Kyle and accepted is actually "package-private" (packages in java are equivalent for namespaces in C#) but some how what has been answered is the closest way to get the same result.

BUT how to get a fully same result as internal ? cant java have a solution for this ? the answer is YES.

it does have. but not with a modifier.
actually the best way to do this is a secret in packaging. the best practice of packing is to pack your classes by their relation not by their type.

many of us use packages named "Models" or "Presenters" and put all our models or presenters in them. while this is wrong. packages should be like "Book" containing "BookModel.java", "BookPresenter.java" , .....

this way you can make them package-private by omitting the modifier and have not any problem because you can access them in any class which need your package-private class because you have a good practice of packaging.

说不完的你爱 2024-11-14 00:34:04

删除访问修饰符与 C# 中的内部类似。

C#

public class A
{
    public static int X;
    internal static int Y;
    private static int Z;
}
internal class B
{
    public static int X;
    internal static int Y;
    private static int Z;
    public class C
    {
        public static int X;
        internal static int Y;
        private static int Z;
    }
    private class D
    {
        public static int X;
        internal static int Y;
        private static int Z;
    }
}

Java

public class A
{
    public static int X;
    static int Y;
    private static int Z;
}
class B
{
    public static int X;
    static int Y;
    private static int Z;
    public class C
    {
        public static int X;
        static int Y;
        private static int Z;
    }
    private class D
    {
        public static int X;
        static int Y;
        private static int Z;
    }
}

来源:http://www .javacamp.org/javavscsharp/internal.html

Dropping the access modifier is similar to internal in C#.

C#

public class A
{
    public static int X;
    internal static int Y;
    private static int Z;
}
internal class B
{
    public static int X;
    internal static int Y;
    private static int Z;
    public class C
    {
        public static int X;
        internal static int Y;
        private static int Z;
    }
    private class D
    {
        public static int X;
        internal static int Y;
        private static int Z;
    }
}

Java

public class A
{
    public static int X;
    static int Y;
    private static int Z;
}
class B
{
    public static int X;
    static int Y;
    private static int Z;
    public class C
    {
        public static int X;
        static int Y;
        private static int Z;
    }
    private class D
    {
        public static int X;
        static int Y;
        private static int Z;
    }
}

Source: http://www.javacamp.org/javavscsharp/internal.html

十二 2024-11-14 00:34:04

是的。它称为包私有,您只需定义类而不使用任何修饰符:


包 com.blah;
类 Foo{ }

Yes. It's called package private, you just define the class without any modifiers:


package com.blah;
class Foo{ }

吐个泡泡 2024-11-14 00:34:04

我不熟悉 C#,但在 Java 中,默认保护是某些内容只能在包内访问:

public=任何人都可以访问

private=仅在当前类中可访问

protected=在包内或继承自的任何类中可访问当前类

默认=包内可访问

我一直认为应该有一种方法可以说“可以由继承当前类的任何类访问,但不能从其他任何地方、这个包或任何其他类访问”。但没有。

I'm not familiar with C#, but in Java the default protection is that something is only accessible within the package:

public=accessible by anyone

private=accessible only within the current class

protected=accessible within the package or in any class that inherits from the current class

default=accessible within the package

I've always thought there should be a way to say "accessible by any class that inherits from the current class but not from anywhere else, this package or any other". But there isn't.

十二 2024-11-14 00:34:04

大多数答案(包括已接受的答案)都谈论包私有。但这与 C# 中的内部相去甚远。

在 Java 中,您只希望同一源根目录中的类访问同一源根目录中的另一个类,并且可能在不同的包中(仍然在同一源根目录中),同时保持包私有,这是根本不可能的。如果您使用包私有,那么只有同一包中的类才能访问该资源。然而,即使同一包中的下一级类(即该包下的另一个包)也无法访问该类。

 a.b.c.A --> class A
 a.b.c.d.B --> public class B

这里B无法访问A。不幸的是,这迫使您将 A 标记为公共。

主要区别在于 C# 或 Java 打包编译代码的方式。 C# 可以将它们标记为内部(即不从程序集中导出符号),但 Java 将它们打包为 jar 文件,并且导入 jar 的方式完全不同。


那么实际的解决方案是什么:
首先,没有强制解决方案。人们可以使用javadocs注释将一个类标记为内部类并阻止人们使用它,声明它是内部的并且可以进行很多更改,它不是一部分公共 API 的一部分,只是不要使用它,否则如果迁移到新版本,您可能会遇到麻烦...

我看到有两种方法可以做到这一点:

  1. 将您的包命名为内部:

    包org.mycoollib.api;
    /** 这个类是我的公共 API 的一部分*/
    公共A类{
      //...
    }
    
    包 org.mycoollib.internal;
    /** 这是一个内部类,不要使用它,否则你的代码可能不会
     在新版本中工作*/
    公开课B{
      //...
    }
    

一些现实生活中的例子:jdk.internalio.netty.util.internal等等。当我将 internal 视为包名称时,我只是避免使用其中的类。

  1. 使用注释来实现与1相同的目标

    包org.mycoollib.api;
    /** 这个类是我的公共 API 的一部分*/
    公共A类{
      //...
    }
    
    包 org.mycoollib.internal;
    /** 这是一个内部类,不要使用它,否则你的代码可能不会
     在新版本中工作*/
    @内部的
    公开课B{
      //...
    }
    

示例:android.annotation.SystemApi, org.apache.poi.Internal

甚至可能是提供此类注释的库以及 Maven 插件以在构建过程中向人们发出警告。

因此,解决方案的思路是:我们只是警告人们不要使用它,因为我们不保证它的名称和方法不会改变。如果他们仍然坚持使用它,那就这样吧。他们知道风险。

Most of the answers (including the accepted one) talk about package-private. But that is far from the internal in C#.

A use case where you want only your classes in the same source root to access another class in the same source root and possibly at different packages (still in the same source root) while keeping it package-private is simply impossible in Java. If you use package-private then only the classes in the same package will have access to that resource. However, even the classes one level down in the same package (i.e. another package under that package) cannot access that class.

 a.b.c.A --> class A
 a.b.c.d.B --> public class B

Here B cannot access A. This forces you to unfortunately mark A as public.

The main difference is in the way C# or Java packs the compiled code. C# can mark them as internal (i.e. do not export the symbol from the assembly) but Java packs as jar files and the way a jar is imported is completely different.


So what is the practical solution:
Well first of all there is no forcing solution. One can use javadocs or annotations to mark a class as internal and discourage people from using it, stating that it is internal and it can be changed a lot, it is not part of the public API, just don't use it or you might get into trouble if you migrate to a new release...

I see two ways of doing this:

  1. name your package as internal:

    package org.mycoollib.api;
    /** This class is part of my public API*/
    public class A{
      //...
    }
    
    package org.mycoollib.internal;
    /** This an internal class, don't use it or your code might not
     work in a new release */
    public class B{
      //...
    }
    

Some real life examples: jdk.internal, io.netty.util.internal and so on. When I see internal as a package name I simply avoid using the classes in that.

  1. Use annotations to achieve the same goal as in 1

    package org.mycoollib.api;
    /** This class is part of my public API*/
    public class A{
      //...
    }
    
    package org.mycoollib.internal;
    /** This an internal class, don't use it or your code might not
     work in a new release */
    @Internal
    public class B{
      //...
    }
    

Example: android.annotation.SystemApi, org.apache.poi.Internal

There might even be libraries out there to provide such kind of annotations as well as maven plugins to warn people during their builds.

As a result, the solution is in the way of thinking: We simply warn people not to use it because we don't guarantee that its name and methods won't change. If they still insist on using it, then so be it. They know the risk.

无妨# 2024-11-14 00:34:04

您可以将类包制作为本地的。这是类的默认范围。即你没有访问修饰符的地方。

如果你真的想在某个时候创建​​一个注释,例如@package_local,我会在我特别希望它成为本地包的地方执行此操作,而不仅仅是将其保留为未指定的位置。

You can make a class package local. This is the default scope for a class. i.e. where you have no access modifiers.

If you really want to put sometime you can create an annotation e.g. @package_local, I do this in places where I speicifc want it to be package local and didn't just leave it unspecificed.

预谋 2024-11-14 00:34:04

是的,默认(包私有)访问级别。只需在类定义中省略任何访问修饰符即可获得所需的内容。

Yes, the default (package private) access level. Just leave out any access modifier on your class definition and you get what you want.

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