1

答えが見つからない Java の問題があります。クラスBを拡張するクラスからのみ呼び出す必要があるメソッドa()を含むクラスAがあります。今のところ、私が見つけることができる最良の解決策は以下のものです。

Class callerClass = Reflection.getCallerClass(2);
if (!B.class.isAssignableFrom(callerClass))
    throw new InvalidMethodCallException("A.a", B.class.getName(), callerClass.getName());

InvalidMethodCallException私自身の例外であること。

ただし、実行時に呼び出しが行われるため、ソリューションに完全に満足しているわけではありません。a()代わりに、それにアクセスできるように宣言したいのですがB、リフレクションはコストのかかるプロセスであるため、これはコンパイル時にチェックされます。

そうする適切な方法を知っていますか?

ご協力ありがとうございました。

編集:追加情報

簡単な例は、ユーザーがconnect(port1, port2)classEdgeでメソッドを呼び出すのではなくaddEdge(edge, port1, port2)、クラスからメソッドを呼び出すGraphことです。これは、グラフが内部にあるエッジも記憶する必要があるためです。

クラスからの私のコードは次のGraphとおりです。

        public void addEdge (Edge edge, Port firstPort, Port secondPort)
            throws DuplicateEdgeInGraphException, AttachedNodeNotInGraphException, GraphDescriptionModelException
        {

            // Must not appear in the graph
            if (this.edges.contains(edge))
                throw new DuplicateEdgeInGraphException(edge);

            // The nodes attached to the ports must be in the graph
            if (!this.nodes.contains(firstPort.getNode()))
                throw new AttachedNodeNotInGraphException(firstPort);
            if (!this.nodes.contains(secondPort.getNode()))
                throw new AttachedNodeNotInGraphException(secondPort);

            // We connect the edge and add it
            edge.connect(firstPort, secondPort);
            this.edges.add(edge);

        }

そしてクラスからEdge

        public void connect (Port portOne, Port portTwo)
            throws InvalidMethodCallException, WrongPortsDirectionsException, WrongPortsSizesException, GraphDescriptionModelException
        {

            // We check the reserved method call
            Class callerClass = Reflection.getCallerClass(2);
            if (!Graph.class.isAssignableFrom(callerClass))
                throw new InvalidMethodCallException("Edge.connect", Graph.class.getName(), callerClass.getName());

            // We check the directions of the ports
            if ((portOne.isInputPort() && !portOne.isInputOutputPort() && !portTwo.isOutputPort())
            || (portTwo.isInputPort() && !portTwo.isInputOutputPort() && !portOne.isOutputPort())
            || (portOne.isOutputPort() && !portOne.isInputOutputPort() && !portTwo.isInputPort())
            || (portTwo.isOutputPort() && !portTwo.isInputOutputPort() && !portOne.isInputPort()))
                throw new WrongPortsDirectionsException(portOne, portTwo);

            // We check the sizes of the ports
            if ((portOne.isInputPort() && !portOne.isInputOutputPort() && portOne.getSize() < portTwo.getSize())
            || (portTwo.isInputPort() && !portTwo.isInputOutputPort() && portTwo.getSize() < portOne.getSize())
            || (portOne.isOutputPort() && !portOne.isInputOutputPort() && portOne.getSize() > portTwo.getSize())
            || (portTwo.isOutputPort() && !portTwo.isInputOutputPort() && portTwo.getSize() > portOne.getSize())
            || (portOne.isInputOutputPort() && portTwo.isInputOutputPort() && portOne.getSize() != portTwo.getSize()))
                throw new WrongPortsSizesException(portOne, portTwo);

            // We avoid similar edges
            for (Edge portOneEdge : portOne.getConnectedEdges())
                if (portOneEdge.getOppositePort(portOne).equals(portTwo))
                    throw new SimilarEdgeAlreadyExistsException(portOneEdge);

            // Ports' attributes
            portOne.getConnectedEdges().add(this);
            portTwo.getConnectedEdges().add(this);

            // Attributes
            this.portOne = portOne;
            this.portTwo = portTwo;

        }

これが問題の理解に役立つことを願っています。

編集:みんなありがとう!

4

2 に答える 2

0

これを行うためのきれいな方法はないと思います。別のデザインを検討してください。

クラス A がクラス B とその子クラスのみを提供するようにする場合は、クラス A を B の内部クラスとして定義し、保護されたアクセス修飾子を与えます。

于 2013-05-23T10:18:26.010 に答える