Java:如何在编译时找到方法的调用者?

时间:2013-05-23 10:10:04

标签: java reflection methods compilation runtime

我有一个Java问题,我找不到答案:我有一个 A 类,其中包含一个只能从一个方法调用的方法 a()课程延伸班 B 。目前,我能找到的最佳解决方案如下:

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)中调用方法Edge,而是从addEdge(edge, port1, port2)调用方法Graph class,因为图形还必须记住内部有什么边缘。

以下是我在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;

        }

希望这有助于理解问题。

编辑:感谢所有人!

2 个答案:

答案 0 :(得分:1)

您可以查看Annotation Processing Tool。它允许您编译编译时注释并在编译代码时产生警告/错误。

答案 1 :(得分:0)

我认为没有一种干净的方法可以做到这一点。请考虑另一种设计。

如果您希望A类仅提供B类及其子类,请将A类定义为B的内部类,并为其提供受保护的访问修饰符。