static <T> T copyTo(Object object, Class<T> targetClass, JSONWriter.Feature... features) {
        if (object == null) {
            return null;
        }

        Class<?> objectClass = object.getClass();

        boolean fieldBased = false, beanToArray = false;
        long featuresValue = JSONFactory.defaultReaderFeatures;
        for (int i = 0; i < features.length; i++) {
            JSONWriter.Feature feature = features[i];
            featuresValue |= feature.mask;
            if (feature == JSONWriter.Feature.FieldBased) {
                fieldBased = true;
            } else if (feature == JSONWriter.Feature.BeanToArray) {
                beanToArray = true;
            }
        }

        ObjectWriter objectWriter = defaultObjectWriterProvider.getObjectWriter(objectClass, objectClass, fieldBased);
        ObjectReader objectReader = defaultObjectReaderProvider.getObjectReader(targetClass, fieldBased);

        if (objectWriter instanceof ObjectWriterAdapter && objectReader instanceof ObjectReaderBean) {
            List<FieldWriter> fieldWriters = objectWriter.getFieldWriters();

            if (objectReader instanceof ObjectReaderNoneDefaultConstructor) {
                Map<String, Object> map = new HashMap<>(fieldWriters.size(), 1F);
                for (int i = 0; i < fieldWriters.size(); i++) {
                    FieldWriter fieldWriter = fieldWriters.get(i);
                    Object fieldValue = fieldWriter.getFieldValue(object);
                    map.put(fieldWriter.fieldName, fieldValue);
                }

                return (T) objectReader.createInstance(map, featuresValue);
            }

            T instance = (T) objectReader.createInstance(featuresValue);
            for (int i = 0; i < fieldWriters.size(); i++) {
                FieldWriter fieldWriter = fieldWriters.get(i);
                FieldReader fieldReader = objectReader.getFieldReader(fieldWriter.fieldName);
                if (fieldReader == null) {
                    continue;
                }

                Object fieldValue = fieldWriter.getFieldValue(object);

                Object fieldValueCopied;
                if (fieldWriter.fieldClass == Date.class
                        && fieldReader.fieldClass == String.class) {
                    fieldValueCopied = DateUtils.format((Date) fieldValue, fieldWriter.format);
                } else if (fieldWriter.fieldClass == LocalDate.class
                        && fieldReader.fieldClass == String.class) {
                    fieldValueCopied = DateUtils.format((LocalDate) fieldValue, fieldWriter.format);
                } else if (fieldValue == null || fieldReader.supportAcceptType(fieldValue.getClass())) {
                    fieldValueCopied = fieldValue;
                } else {
                    fieldValueCopied = copy(fieldValue);
                }

                fieldReader.accept(instance, fieldValueCopied);
            }

            return instance;
        }

        byte[] jsonbBytes;
        try (JSONWriter writer = JSONWriter.ofJSONB(features)) {
            writer.config(JSONWriter.Feature.WriteClassName);
            objectWriter.writeJSONB(writer, object, null, null, 0);
            jsonbBytes = writer.getBytes();
        }

        try (JSONReader jsonReader = JSONReader.ofJSONB(
                jsonbBytes,
                JSONReader.Feature.SupportAutoType,
                JSONReader.Feature.SupportClassForName)
        ) {
            if (beanToArray) {
                jsonReader.context.config(JSONReader.Feature.SupportArrayToBean);
            }

            return (T) objectReader.readJSONBObject(jsonReader, null, null, 0);
        }
    }
Builds a new instance of targetClass using the properties of the specified object

@param object the specified object will be copied
@param targetClass the specified target class
@param features the specified features is applied to serialization
@since 2.0.16
core/src/main/java/com/alibaba/fastjson2/JSON.java