Java 通知超类关于子类的创建

Java 通知超类关于子类的创建,java,Java,子类完全初始化后,有没有办法自动将通知从子类发送到超类。E完成子类构造函数之后 动机 基类必须提供一些处理类字段列表的默认方法。由于子类字段只有在创建子类之后才能在父类中访问,所以基类不能在基类构造函数中读取这些子类字段。一种解决方案是在需要处理这些字段的每个基本方法的开头读取子类字段。由于反射速度慢,最好使用延迟初始化 我很好奇Java中是否有一些不广为人知的回调机制,它允许定义一些“子类创建的回调”,这样我就能够在不使用延迟初始化的情况下初始化这些字段,从而实现更好的可维护性 我知道可以跟踪

子类完全初始化后,有没有办法自动将通知从子类发送到超类。E完成子类构造函数之后

动机

基类必须提供一些处理类字段列表的默认方法。由于子类字段只有在创建子类之后才能在父类中访问,所以基类不能在基类构造函数中读取这些子类字段。一种解决方案是在需要处理这些字段的每个基本方法的开头读取子类字段。由于反射速度慢,最好使用延迟初始化

我很好奇Java中是否有一些不广为人知的回调机制,它允许定义一些“子类创建的回调”,这样我就能够在不使用延迟初始化的情况下初始化这些字段,从而实现更好的可维护性

我知道可以跟踪对象e的释放。G通过
finalize()

示例

假设您想要创建一个数据库
实体
类(我知道有基于ORM的解决方案,但这只是为了说明类似的问题),它将能够根据实体的类字段生成SQL语句,如create TABLE、INSERT、UPDATE、DELETE。所以基类将负责读取类字段并生成这些语句。要创建实体,只需扩展
实体
,并使用一些字段注释,如
@Column
@Id
@AutoIncrement

class Entity {
    public String getCreateTableStatement() {
        // lazy-initialize list of class fields and produce statement...
    }

    public String getInsertPreparedStatement() {
        // lazy-initialize list of class fields and produce statement...
    }

    // update, delete, ...
}
子类示例

public Person extends Entity {
    @Id public int id;
    @Column public String name;
}
目标


替换延迟初始化的另一种模式将有助于减少重复代码的数量。理想情况下,子类不必定义任何其他内容,只需“
扩展实体”

不清楚您要做什么,但一般来说,许多与对象创建相关的问题都可以通过使用封装创建过程的。通过这种方式,您可以在单个构造函数调用中实现更多功能:

public static MySubClass createSubClass() {
    MySubClass subClass = new MySubClass();
    subClass.baseClassMethodThatManipulatesFields();
    return subClass;
}

请注意(正如其他人所指出的),继承可能不是解决问题的最佳方案。您在
实体中列出的方法可能由使用反射初始化类的工厂负责。

我不是在问为什么。若你们想和你们的答案完全一样,那个么父对象可以通过构造函数完全访问它的子对象。是的,我知道此时子对象尚未完全初始化,但注释信息在此步骤中可用

这是一个例子:

import org.apache.commons.lang3.reflect.MethodUtils;

import javax.persistence.Id;
import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.util.ArrayList;
import java.util.List;

    public class Entity {
        protected Entity() {
            List<AccessibleObject> ids = getAccessibleObjectWithAnnotation(Id.class);
            List<AccessibleObject> columns = getAccessibleObjectWithAnnotation(Column.class);
        }

        private List<AccessibleObject> getAccessibleObjectWithAnnotation(Class<? extends Annotation> cls) {
            List<AccessibleObject> res = new ArrayList<>();
            res.addAll(FieldUtils.getFieldsListWithAnnotation(getClass(), cls));
            res.addAll(MethodUtils.getMethodsListWithAnnotation(getClass(), cls));
            return res;
        }
    }
import org.apache.commons.lang3.reflect.MethodUtils;
导入javax.persistence.Id;
导入java.lang.annotation.annotation;
导入java.lang.reflect.AccessibleObject;
导入java.util.ArrayList;
导入java.util.List;
公共类实体{
受保护实体(){
列表Id=getAccessibleObjectWithAnnotation(Id.class);
List columns=getAccessibleObjectWithAnnotation(Column.class);
}

私有列表GetAccessibleObject WithAnnotation(类这个问题似乎是一个可能的类型问题。基类应该完全不知道子类,并且不是所有的问题都应该通过继承来解决。你确定组合不会更好吗?@HovercraftFullOfEels我想为从给定b扩展的任何子类提供一些基于类字段的默认方法ase类,因此继承是原位的,否则我需要在每个子类上重复相同的方法。或者你可以让两个类都是同一父类的子类,但它们仍然通过组合相关。可能有很多方法可以剥除这条鱼的皮。如何在构造函数创建之前获得对子类对象的引用结束?建议:让你的问题少一些理论性的东西,而是更具体一些,包括一个小的实际代码示例,说明你正在尝试做什么。这是一个答案并没有回答Java是否支持一些创建回调的问题,但是我喜欢这个解决方案,所以几天后我可能会接受这个答案。谢谢!我不这么认为hink认为Java中存在这样的构造函数回调,但您当然可以将其烘焙到工厂方法中。