簡體   English   中英

Java中有沒有類似內部類的東西?

[英]Is there anything like an Internal class in Java?

在 C# 中,您可以將類標記為internal類,以便它只能從同一個包中訪問。 Java中有沒有類似的東西?

您可以通過從類的聲明中省略安全修飾符(public、private)來創建包私有類。

package com.sample;

class MyPackagePrivateClass
{
    ...
}

刪除訪問修飾符類似於 C# 中的 internal。

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;
    }
}

爪哇

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

這個問題之前有一個公認的答案,但我認為對於來自 .Net 的 Java 新手來說,答案並不完全清楚。

java 在 C# 中是否有一些完全等效的內部修飾符? 簡短的回答是否定的(但你可以通過某種方式實現它,我會告訴你)!!

C# 中的 internal 實際上是一個“程序集私有”修飾符。 什么是程序集?

程序集是您項目的任何產品(C# 中的 DLL 或 EXE - Java 中的等價物可以是 JAR 文件)

java中的內部沒有任何確切的等價物。 並且 Bryan Kyle 回答並接受的實際上是“包私有”(Java 中的包與 C# 中的命名空間等效),但某些已回答的方式是獲得相同結果的最接近方法。

但是如何獲得與 internal 完全相同的結果? java 不能對此有解決方案嗎? 答案是肯定的。

它確實有。 但沒有修飾符。 實際上,最好的方法是在包裝中隱藏秘密。 打包的最佳實踐是按照類的關系而不是類型來打包類。

我們中的許多人使用名為“模型”或“演示者”的包,並將我們所有的模型或演示者放入其中。 雖然這是錯誤的。 包應該像 "Book" 包含 "BookModel.java", "BookPresenter.java" , .....

通過這種方式,您可以通過省略修飾符使它們成為包私有的,並且沒有任何問題,因為您可以在需要包私有類的任何類中訪問它們,因為您有很好的打包實踐。

是的。 它稱為包私有,您只需定義沒有任何修飾符的類:

package com.blah; class Foo{ }

我不熟悉 C#,但在 Java 中,默認保護是某些內容只能在包內訪問:

public=任何人都可以訪問

private=只能在當前類中訪問

protected=可在包內或從當前類繼承的任何類中訪問

默認=可在包內訪問

我一直認為應該有一種方法可以說“可由從當前類繼承的任何類訪問,但不能從其他任何地方、此包或任何其他類訪問”。 但沒有。

您可以在本地創建類包。 這是類的默認范圍。 即您沒有訪問修飾符的地方。

如果您真的想放置某個時間,您可以創建一個注釋,例如@package_local,我會在我特別希望它是本地包的地方執行此操作,而不僅僅是未指定它。

是的,默認(包私有)訪問級別。 只需在您的類定義中省略任何訪問修飾符,您就會得到您想要的。

大多數答案(包括已接受的答案)都涉及包私有。 但這與 C# 的internal相去甚遠。

在 Java 中,您只希望同一源根中的類訪問同一源根中和可能位於不同包(仍在同一源根中)中的另一個類,同時保持包私有,這是不可能的。 如果您使用 package-private,則只有同一包中的類才能訪問該資源。 然而,即使是同一個包中低一級的類(即該包下的另一個包)也不能訪問該類。

 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. 將您的包命名為內部:

     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{ //... }

一些現實生活中的例子: jdk.internalio.netty.util.internal等等。 當我將internal視為包名稱時,我只是避免使用其中的類。

  1. 使用注解實現與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{ //... }

示例: android.annotation.SystemApiorg.apache.poi.Internal

甚至可能有一些庫可以提供此類注釋以及 Maven 插件以在構建過程中警告人們。

因此,解決方案是在思考:我們只是警告人們不要使用它,因為我們不保證它的名稱和方法不會改變。 如果他們仍然堅持使用它,那就這樣吧。 他們知道風險。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM