C++のような、Javaのフレンドコンセプトをどのように実装しますか?JavaのFriendコンセプトの実装
答えて
JavaにはC++のフレンドキーがありません。しかし、それをエミュレートする方法があります。実際よりはるかに正確な制御を与える方法です。あなたはAとB B usageExample(
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);
}
}
A.にいくつかのプライベートメソッドまたはフィールドへのアクセスを必要とするが)、これはどのように動作するかを示したクラスがあるとします。 Bのインスタンスは、Aのインスタンスのプライベートフィールドまたはメソッドにアクセスすることはできません。しかし、giveKeyTo()を呼び出すと、クラスBがアクセスできます。有効なBを引数として必要とするため、他のクラスはそのメソッドにアクセスできません。コンストラクタはprivateです。
クラスBは、キーに渡されたメソッドのいずれかを使用できます。これは、C++の友人キーワードよりもセットアップが煩雑ではあるが、はるかにきめ細かくなっている。クラスAは、どのメソッドを正確にどのクラスに公開するかを選択することができます。
ここで、AはBのすべてのインスタンスとBのサブクラスのインスタンスへのアクセスを許可します。後者が望ましくない場合、giveKeyTo()メソッドは内部的にotherの正確な型をgetClass )、正確でない場合は例外をスローします。
非常に良い。これを実装するより良い方法は、潜在的なセキュリティリスクを回避して、クラス 'B'を' final'として宣言することでしょう。 – user991710
Javaでは、両方の(またはそれ以上の)クラスを同じパッケージに入れることができます。 protected
修飾子を持つすべてのメソッドとフィールドは、そのパッケージ内のすべてのクラスから直接アクセスできます。
しかし、既存のレガシーコードがすでに存在し、リファクタリングが面倒になり、フィールドやメソッドの可視性を変更したくない場合、そのような友人関係を設定することはオプションになる可能性があります。私は同意する、それは非常に読みやすく、推奨されませんが、それは迅速な修正として動作します。 –
私は、これが永久に一時的な、または一時的な永久的なオプションになったときに、オプションの、最悪の場合、技術的な借金のサブプライムレベルへようこそ最後の溝を指摘する必要があると感じています。 –
私が知っているほとんどすべての人が、影響を受けるメソッドをpublicとして定義していますが、あなたのアプローチは面白いです。 – 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
はnull以外B.ToA
トークンを生成することができます。 A2
があまりにも友人B
したい場合A
とB
両方がサードパーティにこのトークンをリークしていない場合は、他の 誰もA.foo()
を呼び出すことはできません、それは別のトークンタイプを必要とします。それが同じトークンタイプの場合、A
はB
のタイプのトークンを持っているので、からA2
のふりをすることができます。
チェックは実行時に行われ、コンパイル時ではなく完全ではありません。しかし、第三者がnull
でA.foo()
を呼び出すだけなので、大したことではありません。コンパイル時に確認したい無罪のミスではありません。おそらく悪意のあるので、コンパイル時に呼び出し元に警告する気にはなりません。
- 1. MVC実装 - コンセプト(ABAP SAP)
- 2. C++のコンセプトを実装したコンパイラ
- 3. ajaxはコンセプトと実装です
- 4. JavaのGCコンセプト:CMSInitiatingOccupancyFraction
- 5. メッセージ指向のミドルウェア - このコンセプトを実装する製品?
- 6. PHPアプリケーション用のSSOコンセプトを実装しました
- 7. JavaでのJavaの実装
- 8. パッケージとJavaの継承コンセプト
- 9. Javaジェネリックファクトリパターンの実装
- 10. javaのhash()実装
- 11. Javaコンパイラの実装
- 12. Java:ガウスブラーの実装
- 13. クイックユニオンJavaの実装
- 14. Javaリングの実装
- 15. Javaマージソートの実装
- 16. JavaのRFC2898DeriveBytes実装
- 17. Java RMIの実装
- 18. Java - サービスプロバイダの実装
- 19. Java OCRの実装
- 20. Java実装のキーリスト。
- 21. Javaハッシュシンボルテーブルの実装
- 22. Javaプリミティブの実装
- 23. Long.numberOfTrailingZerosのJava実装()
- 24. Java ESAPIの実装
- 25. セグメントツリーのJava実装
- 26. コンセンサスアルゴリズムのJava実装
- 27. Javaバブルソートアルゴリズムの実装
- 28. SAT Javaの実装
- 29. クロックプロキャッシュ - java実装
- 30. CircularArrayQueue実装Java
私がC++でコーディングしても、私は 'friend'を非常に控えめに使っています。すべてで使用できる公開インタフェースを提供する方がはるかに安全です。 –
私は自分のコードでJavaの友人概念を使用していません。私は好奇心のためだけに好奇心旺盛でした。 –
@ Code-Guruパブリックインターフェイスはどのように役立つでしょうか?私はここで何かを逃しているかもしれない。もっと詳しい情報を提供するリンクを投稿できますか? –