Java 如何处理所有子类';超类中的成员';建造师?

Java 如何处理所有子类';超类中的成员';建造师?,java,inheritance,reflection,subclassing,Java,Inheritance,Reflection,Subclassing,我想编写一个类,比如JComponentEx,它将枚举所有子类成员并将其添加到对象中 这样我就能写作了 class MyComponent extends JComponentEx { private JLabel mylabel = new JLabel(); private JTextField mytext = new JTextField(); } 这将导致自动调用 this.add(mylabel); this.add(mytext); 我理解在Swing的情

我想编写一个类,比如JComponentEx,它将枚举所有子类成员并将其添加到对象中

这样我就能写作了

class MyComponent extends JComponentEx {

    private JLabel mylabel = new JLabel();

    private JTextField mytext = new JTextField();

}
这将导致自动调用

this.add(mylabel);
this.add(mytext);
我理解在Swing的情况下它会导致一些问题。我的问题是如何在原则上落实这一想法

更新

简而言之,我想用成员定义填充列表

更新2

如果在构造函数内运行加法,则不会看到成员,因为超类构造函数是在初始化子类实例之前执行的:

public class Try_Reflection_01 {

    private final static Logger log = LoggerFactory
            .getLogger(Try_Reflection_01.class);

    public static interface IAutoAdd {
    }

    @SuppressWarnings("serial")
    public static class JComponentEx extends JComponent {

        public JComponentEx() {
            updateComponents();
        }

        protected void updateComponents() {
            log.info("In updateComponents()");
            for (Field f : getClass().getFields()) {

                try {
                    Object x = f.get(this);
                    log.info("Checking '{}' = {}", f.getName(), x);
                    if (x instanceof IAutoAdd) {
                        log.info("Adding");
                        add((JComponent)x);
                    }
                    else {
                        log.info("Not adding");
                    }

                } catch (IllegalArgumentException e) {
                    log.error("Error getting member", e);
                } catch (IllegalAccessException e) {
                    log.error("Error getting member", e);
                }

            }
        }
    }

    public static class JMyComponent extends JComponentEx implements IAutoAdd {
        public JLabel label = new JLabel("my label");
    }

    public static void main(String[] args) {
        JMyComponent component = new JMyComponent();
    }
}
输出

[main] INFO test.java.Try_Reflection_01 - In updateComponents()
[main] INFO test.java.Try_Reflection_01 - Checking 'label' = null
[main] INFO test.java.Try_Reflection_01 - Not adding
[main] INFO test.java.Try_Reflection_01 - Checking 'WHEN_FOCUSED' = 0
[main] INFO test.java.Try_Reflection_01 - Not adding
[main] INFO test.java.Try_Reflection_01 - Checking 'WHEN_ANCESTOR_OF_FOCUSED_COMPONENT' = 1
[main] INFO test.java.Try_Reflection_01 - Not adding
[main] INFO test.java.Try_Reflection_01 - Checking 'WHEN_IN_FOCUSED_WINDOW' = 2
[main] INFO test.java.Try_Reflection_01 - Not adding
[main] INFO test.java.Try_Reflection_01 - Checking 'UNDEFINED_CONDITION' = -1
[main] INFO test.java.Try_Reflection_01 - Not adding
[main] INFO test.java.Try_Reflection_01 - Checking 'TOOL_TIP_TEXT_KEY' = ToolTipText
[main] INFO test.java.Try_Reflection_01 - Not adding
[main] INFO test.java.Try_Reflection_01 - Checking 'TOP_ALIGNMENT' = 0.0
[main] INFO test.java.Try_Reflection_01 - Not adding
[main] INFO test.java.Try_Reflection_01 - Checking 'CENTER_ALIGNMENT' = 0.5
[main] INFO test.java.Try_Reflection_01 - Not adding
[main] INFO test.java.Try_Reflection_01 - Checking 'BOTTOM_ALIGNMENT' = 1.0
[main] INFO test.java.Try_Reflection_01 - Not adding
[main] INFO test.java.Try_Reflection_01 - Checking 'LEFT_ALIGNMENT' = 0.0
[main] INFO test.java.Try_Reflection_01 - Not adding
[main] INFO test.java.Try_Reflection_01 - Checking 'RIGHT_ALIGNMENT' = 1.0
[main] INFO test.java.Try_Reflection_01 - Not adding
[main] INFO test.java.Try_Reflection_01 - Checking 'WIDTH' = 1
[main] INFO test.java.Try_Reflection_01 - Not adding
[main] INFO test.java.Try_Reflection_01 - Checking 'HEIGHT' = 2
[main] INFO test.java.Try_Reflection_01 - Not adding
[main] INFO test.java.Try_Reflection_01 - Checking 'PROPERTIES' = 4
[main] INFO test.java.Try_Reflection_01 - Not adding
[main] INFO test.java.Try_Reflection_01 - Checking 'SOMEBITS' = 8
[main] INFO test.java.Try_Reflection_01 - Not adding
[main] INFO test.java.Try_Reflection_01 - Checking 'FRAMEBITS' = 16
[main] INFO test.java.Try_Reflection_01 - Not adding
[main] INFO test.java.Try_Reflection_01 - Checking 'ALLBITS' = 32
[main] INFO test.java.Try_Reflection_01 - Not adding
[main] INFO test.java.Try_Reflection_01 - Checking 'ERROR' = 64
[main] INFO test.java.Try_Reflection_01 - Not adding
[main] INFO test.java.Try_Reflection_01 - Checking 'ABORT' = 128
[main] INFO test.java.Try_Reflection_01 - Not adding

将它们存储在列表中,而不是单独的字段中

protected List<JComponent> components = new ArrayList<>();

// initializer
{
 components.add(new JLabel());
 components.add(new JTextField());
}
另一种储存方式:

protected Map<String, JComponent> components = new HashMap<>();

{
 components.put("inputfield", new JTextField());
}
protectedmap components=newhashmap();
{
put(“inputfield”,newjtextfield());
}
这将允许您通过使用键作为标识符来轻松修改组件

如果您真的想为此使用反射:

public class MyComponent {
    private JLabel mylabel = new JLabel();
    private JTextField mytext = new JTextField();

    private String someString;

    public List<JComponent> getComponents() throws IllegalArgumentException,
            IllegalAccessException {
        Field[] fields = this.getClass().getDeclaredFields();

        List<JComponent> list = new ArrayList<>();
        for (Field field : fields) {
            Object someField = field.get(this);
            if (someField instanceof JComponent) {
                list.add((JComponent) someField);
            }
        }

        return list;
    }
}

public class Test {
    public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException{
        MyComponent comp = new MyComponent();
        System.out.println(comp.getComponents().size());
    }
}
公共类MyComponent{
私有JLabel mylabel=新JLabel();
私有JTextField mytext=新JTextField();
私有字符串someString;
public List getComponents()引发IllegalArgumentException,
非法访问例外{
Field[]fields=this.getClass().getDeclaredFields();
列表=新的ArrayList();
用于(字段:字段){
objectsomefield=field.get(this);
if(JComponent的某个字段实例){
添加((JComponent)someField);
}
}
退货清单;
}
}
公开课考试{
公共静态void main(字符串[]args)抛出IllegalArgumentException、IllegalAccessException{
MyComponent comp=新的MyComponent();
System.out.println(comp.getComponents().size());
}
}
输出:

二,


您需要使用反射-类似于:

for(Field f: getClass().getFields()) {
  Object x = f.get(this);
  if(x instanceof JComponent) add(x);
}

请注意,我给出的仅适用于公共领域;访问私有字段有点棘手,而且需要安全权限,因此在未签名的小程序中不起作用。

它们已经存储在列表中,就像JComponent一样。现在我只想用成员声明填充这个列表。@SuzanCioc:你说的“成员声明”是什么意思?我想要那一行
private JLabel=new JLabel()
自动将
label
添加到基础列表中,无需显式写入
add(label)
getDeclaredFields()
也适用于私有字段
getFields()
仅为公共类。是的,但我希望在超类中执行此操作,以便子类不包含任何与此相关的代码。@RobinGreen如果我将此代码放入超类构造函数中,它将不会看到子类成员(它们将为
null
)。看看我的最新消息,没错。Java不提供在任何构造函数运行后运行代码的通用方法,但AspectJ和Scala确实提供了该功能。
for(Field f: getClass().getFields()) {
  Object x = f.get(this);
  if(x instanceof JComponent) add(x);
}