如何實現Java中的朋友概念(如C++)?在Java中實現Friend概念
回答
Java沒有C++中的friend關鍵字。然而,有一種方法可以效仿它;這種方式實際上給了更多更精確的控制。假設您有類A和B. B需要訪問一些私有方法或字段A.
public class A {
private int privateInt = 31415;
public class SomePrivateMethods {
public int getSomethingPrivate() { return privateInt; }
private SomePrivateMethods() { } // no public constructor
}
public void giveKeyTo(B other) {
other.receiveKey(new SomePrivateMethods());
}
}
public class B {
private A.SomePrivateMethods key;
public void receiveKey(A.SomePrivateMethods key) {
this.key = key;
}
public void usageExample() {
A anA = new A();
// int foo = anA.privateInt; // doesn't work, not accessible
anA.giveKeyTo(this);
int fii = key.getSomethingPrivate();
System.out.println(fii);
}
}
的usageExample()顯示了這一過程。 B的實例不能訪問A的實例的私有字段或方法。但通過調用giveKeyTo(),B類可以訪問。沒有其他類可以訪問該方法,因爲它需要一個有效的B作爲參數。構造函數是私有的。
然後B類可以使用任何交給密鑰的方法。這雖然比C++好友關鍵字更笨拙,但卻更加細緻。類A可以精確選擇哪些方法公開哪些類。
現在,在上述情況下,A允許訪問B的所有實例和B的子類實例。如果不希望後者,則giveKeyTo()方法可以在內部使用getClass檢查其他類型的實際類型( ),並且拋出異常(如果它不是精確的B)。
非常好。實現這一點的更好方法可能是將'B'類聲明爲'final',從而避免潛在的安全風險。 – user991710
在Java中,您可以將兩個(或更多)類放入同一個包中。包含protected
限定符的所有方法和字段可以直接由該包中的所有類訪問。
事實上,如果現有的遺留代碼已經存在並且重構將會很麻煩並且您不想改變字段和方法的可見性,那麼設置這樣的朋友功能可能是一種選擇。我同意,它不會被高度閱讀或甚至不推薦,但它可以作爲一個快速解決方案。 –
我覺得有必要指出這是最後一個漏洞,出於選擇,最壞的情況,歡迎進入次級水平的技術債務,當它成爲永久性暫時或暫時的永久性選擇時。 –
幾乎所有我認識的人都會將受影響的方法定義爲公開的,但您的方法很有趣 – AlexWien
我想出了另一種實現方法。基本上你可以檢查調用類名的完全限定名。如果它匹配你的「朋友」功能,那麼你給予訪問權限,否則你返回null。
public class A {
private static int privateInt = 31415;
public static int getPrivateInt() {
if(Throwable().getStackTrace()[1].getClassName().equals(new String("example.java.testing.B")))
{
return privateInt;
}
else
{
return null;
}
}
}
package example.java.testing;
public class B {
public void usageExample() {
int foo = A.getPrivateInt; // works only for B
System.out.println(foo);
}
}
假設A.foo()
只能由B
調用。這可以由只能由B
生成的令牌來安排。
public class B
{
public static class ToA { private ToA(){} }
private static final ToA b2a = new ToA();
void test()
{
new A().foo(b2a);
}
}
public class A
{
public void foo(B.ToA b2a)
{
if(b2a==null)
throw new Error("you ain't B");
// ...
}
}
只有B
可以生成一個非空B.ToA
令牌。如果兩個A
和B
不要將此令牌泄漏到第三方, 沒有其他人可以調用A.foo()
如果A2
希望朋友B
過,它需要一個不同的令牌類型。如果它是相同的標記類型,由於A
得到B
類型的標記,因此A
可以假裝爲B
至A2
。
檢查是在運行時完成的,而不是編譯時間,這是不完美的。雖然沒什麼大不了,因爲任何第三方只能調用A.foo()
和null
,它不能是我們想在編譯時檢查的無辜錯誤;它可能是惡意的,所以我們不在乎在編譯時警告調用者。
- 1. MVC實現概念(概念(ABAP SAP)
- 2. oop概念實現
- 3. HashMap實現概念
- 4. 概念在Java
- 5. 在Haskell中實現這個OO概念
- 6. 在rails中實現虛擬概念
- 7. 在Javascript中實現線程概念?
- 8. Boost.geometry實現Polygon概念
- 9. Java swing jframes中最常見的OOP概念在哪裏實現?
- 10. 在Java中實現驅動程序概念
- 11. 我應該如何在Java中實現這個Tree Like概念?
- 12. jmeter中的起搏概念實現
- 13. iphone中的增強現實概念
- 14. 概念實例
- 15. Java ArrayList概念
- 16. Java Array概念
- 17. 實驗IDE概念
- 18. ORM實體概念
- 19. Android增強現實(AR)概念
- 20. 虛擬現實和動感概念
- 21. 實現C++概念的編譯器
- 22. 如何實現一些Ruby概念?
- 23. std :: vector的概念和GCC實現
- 24. Java線程概念
- 25. Java RMI的概念
- 26. LinkedList java Iterator.next概念?
- 27. 瞭解Java中的概念
- 28. 在java或EJB中彙集概念?
- 29. 理解繼承的概念在Java中
- 30. 我們如何在java swing中實現面向對象的概念
即使我用C++編寫代碼,如果有的話,我也會非常謹慎地使用'friend'。提供一個可供所有人使用的公共接口更安全。 –
我的代碼中沒有使用Java中的朋友概念。好奇心,我只是好奇。 –
@ Code-Guru公共界面如何提供幫助?我可能會在這裏錯過一些東西。你可以發佈一些鏈接給出更多的細節? –