简体   繁体   English

Java通用编程:确定类是否扩展了另一个

[英]Java Generic programming: Determining if class extends another

I've a few object (Terminal, Runway, Gate, Airline, workers etc...) that I need to show in a JTable. 我需要在JTable中显示一些对象(终端,跑道,登机门,航空公司,工作人员等)。 I'm trying to build a GenericTableModel (To use with the JTable) that will work for every collection. 我正在尝试构建一个适用于每个集合的GenericTableModel(与JTable一起使用)。 Thing is some of those objects have data structures in it and I don't want to show those structures. 事情是其中一些对象具有数据结构,我不想显示这些结构。 So I'm getting column names by getting the first object from the collection and asking for its declared fields which aren't assignable from AbstractMap or Collection classes. 因此,我通过从集合中获取第一个对象并要求获得其声明的字段来获取列名,这些对象不能从AbstractMap或Collection类分配。 This seems to work for me, I get only the fields I need so far. 这似乎对我有用,到目前为止,我仅获得所需的字段。 Problem start when I try to show the workers. 当我尝试向工人展示时,问题就开始了。 I have a W_Worker abstract class with most of the fields for the worker, and I've different workers such as W_Manager, W_FuelWorker etc... Each of the sub.classes have only 1 or 2 fields, and when I put them in a table using my GenericTableModel I only get the fields from the specific worker without the fields from W_Worker. 我有一个W_Worker抽象类,其中包含大多数用于worker的字段,并且我有不同的worker,例如W_Manager,W_FuelWorker等...每个子类只有1或2个字段,当我将它们放在一个使用我的GenericTableModel的表,我只从特定工作程序中获取字段,而没有从W_Worker中获取字段。

How can I determine in the beginning of the method, if the class extends another class and making it get those fields first? 我如何确定方法的开头,是否该类扩展了另一个类并使其首先获取那些字段?

I'll provide code if this won't be enough to understand. 如果这还不够理解,我将提供代码。 Thanks in advance, Tal 预先感谢,塔尔

Edit: Code added. 编辑:添加代码。

public String[] getColumnName(Collection<T> collection){
     Field fields[] = null;
     String fieldsNames[];
     ArrayList<String> desiredFields = new ArrayList<>();

     for(Object o : collection){
        fields = o.getClass().getDeclaredFields();
        if (o instanceof W_Worker){
            Field[] superFields = o.getClass().getSuperclass().getDeclaredFields();
            Field[] result = new Field[superFields.length + fields.length];
            System.arraycopy(superFields, 0, result, 0, superFields.length);
            System.arraycopy(fields, 0, result, superFields.length, fields.length);
            fields = result;
        }
        break;
     }
     fieldsNames = new String[fields.length];
     for(int i = 0; i<fields.length ;i++){
         if (!Collection.class.isAssignableFrom(fields[i].getType()) && !AbstractMap.class.isAssignableFrom(fields[i].getType())){
            fieldsNames[i] = fields[i].getName();
         }
     }
     for(String field : fieldsNames){
         if (field != null){
             desiredFields.add(field);
         }
     }
     String newFields[] = new String[desiredFields.size()];
     return desiredFields.toArray(newFields);
 }

As you can see I'm currently using instanceof, but this isn't generic enough as it will only work with W_Worker. 如您所见,我当前正在使用instanceof,但这还不够通用,因为它仅适用于W_Worker。

I would consider a Visitor Pattern for this. 我会为此考虑一个访客模式 The visitor would know how to deal with the TableModel. 访客会知道如何处理TableModel。

Somewhat like this: 有点像这样:

public class TableModelVisitor {

   private TableModel model;

   public void visit(Terminal terminal) {
      terminal.accept(this);
   }
   public void visit(Runway runway) {
      runway.accept(this);
   }
   public void visit(Worker worker) {
      worker.accept(this);
   }

   //your methods to treat the model
}

Then you can make every node deal with the visitor and ask it to do something like populating the model: 然后,您可以使每个节点都与访问者打交道,并要求其执行填充模型的操作:

public class Worker {
   public void accept(TableModelVisitor tableModelVisitor) {
      //and here you know everything about your worker and its fields
      //and have access to your visitor table model to configure it.
      tableModelVistor.addField(this.getMyField1());
      tableModelVistor.addField(this.getMyField2());
   }
}

At the end, all you have to do is to create a TableModelVisitor and ask it to populate any model you want. 最后,您要做的就是创建一个TableModelVisitor并要求它填充您想要的任何模型。

TableModelVisitor visitor = new TableModelVisitor(myTableModel);
visitor.visit(anyOfMyObjects);

You're probably using the Class.getDeclaredFields method. 您可能正在使用Class.getDeclaredFields方法。 You want Class.getFields. 您需要Class.getFields。 More information here: http://forgetfulprogrammer.wordpress.com/2011/06/13/java-reflection-class-getfields-and-class-getdeclaredfields/ 此处提供更多信息: http : //forgetfulprogrammer.wordpress.com/2011/06/13/java-reflection-class-getfields-and-class-getdeclaredfields/

For any class you can see what it extends and/or implements by using Reflection. 对于任何类,您都可以使用Reflection查看它的扩展和/或实现。 Afterwards do a comparison vs types of different worker classes you have and call the method you find appropriate. 然后,对您拥有的不同工作者类的类型进行比较,并调用您认为合适的方法。 A fully worked example is in the trail: http://docs.oracle.com/javase/tutorial/reflect/class/classModifiers.html 下面是一个完整的示例: http : //docs.oracle.com/javase/tutorial/reflect/class/classModifiers.html

Thanks everyone, I ended up changing the GenericTableModel to receive a collection and an array of Strings which would include the fields I wanted for my object. 谢谢大家,我最终将GenericTableModel更改为接收一个集合和一个String数组,其中包括我想要的对象字段。 This way I kept it Generic still and get the best result for my project. 这样,我将其保持通用,并为我的项目获得最佳结果。

Thanks for your replies and time. 感谢您的答复和时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM