如何在java中实现关联?

时间:2017-11-04 23:55:45

标签: java oop associations

我正在尝试编写一个java方法,用于发现从特定类到另一个类的关联。如何找到与特定类关联的关联和类?

1 个答案:

答案 0 :(得分:0)

这可能是一个非常复杂的问题,您真的应该编辑您的问题,以提供有关您尝试做什么的更多详细信息。我将尝试解释为什么这比你想象的更困难,同时提供的东西可能足以完成你想要的东西。

我的理解是你想写一个发现" association"的方法。从特定班级到其他班级,以及那些"协会"意味着" has-a"关系。

注意:出于示例代码的目的,我将使用包名称" reflect.findHasARelation"

因此,让我们考虑以下情况:

有一个Car类声明了几个字段:

package reflect.findHasARelation;

public class Car {
    private Motor motor;
    private int weight;
    private FuelTank fuelTank; 
}

我们在同一个包中也有类MotorFuelTank。为简单起见,他们什么都不做。

汽车类:

package reflect.findHasARelation;

public class Motor {}

FuelTank课程:

package reflect.findHasARelation;

public class FuelTank {}

现在让我们编写一些分析Car类的代码:

package reflect.findHasARelation;

import java.lang.reflect.Field;

public class FindHasARelationMain {

    public static void main(String[] args) {

        //It's not clear to me how you need to identify which classes to analyze
        // so for now this is just hardcoded for the purposes of this example.
        analyzeClass(Car.class);

    }

    public static void analyzeClass(Class classToAnalyze){
        //Process all fields of the class
        for(Field field: classToAnalyze.getDeclaredFields()){
            if(Object.class.isAssignableFrom(field.getType())){
                //Assuming you're only interested in non-primitive fields
                // this condition would tell you that the class you're 
                // analyzing is in a "has-a" relationship with whatever 
                // class the field is defined with.
                System.out.println("Class "+classToAnalyze.getName()+" has a field "
                    + field.getName() + " of type "+ field.getType().getName());
            }else{
                System.out.println("Class "+classToAnalyze.getName()+" has a primitive field "
                        + field.getName() + " of type "+ field.getType().getName());
            }
        }
    }

}

当您运行上述课程时,您将看到如下输出:

Class reflect.findHasARelation.Car has a field motor of type reflect.findHasARelation.Motor
Class reflect.findHasARelation.Car has a primitive field weight of type int
Class reflect.findHasARelation.Car has a field fuelTank of type reflect.findHasARelation.FuelTank

到目前为止看起来还不错,对吧?我们可以看到它能够识别Car类在" has-a"与MotorFuelTank的关系。

以下是复杂性的来源:如果字段的类型是界面而不是类,该怎么办?

让我们从创建界面开始:

package reflect.findHasARelation;

public interface Engine {
    public void start();
}

现在让我们创造一种新型汽车:

package reflect.findHasARelation;

public class StandardCar {
    //Declares a field using an interface as the type
    private Engine engine;
    private int weight;
    private FuelTank fuelTank;

    public StandardCar(){
        engine = new StandardEngine();
    }
}

如果我们采用之前的main方法并将Car.class替换为StandardCar.class,那么我们会看到此输出:

Class reflect.findHasARelation.StandardCar has a field engine of type reflect.findHasARelation.Engine
Class reflect.findHasARelation.StandardCar has a primitive field weight of type int
Class reflect.findHasARelation.StandardCar has a field fuelTank of type reflect.findHasARelation.FuelTank

为什么会这样?这是因为在通过reflection分析类定义时,不可能知道在运行时将使用Engine的哪个实现。相反,你只能发现它是某种类型的Engine - 在实际创建类的实例之前,不知道它是什么特定类型的Engine。它甚至可以在实例之间变化,因为我们可以将引擎作为参数并将其传递给构造函数或者setter方法(如果我们想要的话)。在这种情况下,我可以有两个同一个类的实例,它们内部有不同类型的Engine实现。

希望您现在明白为什么您的问题可能比您想象的要复杂得多。