基于QtJambi + Deepseek AI写了一个将字符串转换对应对象的QType类,因为QtJambi初始化QMap等容器太麻烦了,所以写了一个QType类自动填充QMetaType到QT容器,同时也为以后自定义序列化和反序列化实现做准备。String扩展更新。

QType类

package jqt;

import io.qt.core.*;
import java.lang.reflect.*;
import java.util.*;
import java.util.stream.Collectors;

public class QType {
    // 类型映射配置
    private static final Map<String, Class<?>> PRIMITIVE_TYPES = new HashMap<>();
    private static final Map<Class<?>, QMetaType.Type> JAVA_TO_QMETATYPE = new HashMap<>();
    private static final Set<Class<?>> QT_CONTAINERS = new HashSet<>();
    private static final List<String> QT_PACKAGES = Arrays.asList(
            "io.qt.core",
            "io.qt.gui",
            "io.qt.network",
            "io.qt.sql",
            "io.qt.xml",
            "java.util",
            "java.lang"
    );
    static {
        // 初始化基本类型映射
        initPrimitiveMappings();
        initQMetaTypeMappings();
        initQtContainers();
    }

    private static void initPrimitiveMappings() {
        PRIMITIVE_TYPES.put("void", void.class);
        PRIMITIVE_TYPES.put("boolean", boolean.class);
        PRIMITIVE_TYPES.put("byte", byte.class);
        PRIMITIVE_TYPES.put("char", char.class);
        PRIMITIVE_TYPES.put("short", short.class);
        PRIMITIVE_TYPES.put("int", int.class);
        PRIMITIVE_TYPES.put("long", long.class);
        PRIMITIVE_TYPES.put("float", float.class);
        PRIMITIVE_TYPES.put("double", double.class);
        PRIMITIVE_TYPES.put("Boolean", Boolean.class);
        PRIMITIVE_TYPES.put("Byte", Byte.class);
        PRIMITIVE_TYPES.put("Character", Character.class);
        PRIMITIVE_TYPES.put("Short", Short.class);
        PRIMITIVE_TYPES.put("Integer", Integer.class);
        PRIMITIVE_TYPES.put("Long", Long.class);
        PRIMITIVE_TYPES.put("Float", Float.class);
        PRIMITIVE_TYPES.put("Double", Double.class);
        PRIMITIVE_TYPES.put("String", String.class);
    }

    private static void initQMetaTypeMappings() {
        JAVA_TO_QMETATYPE.put(int.class, QMetaType.Type.Int);
        JAVA_TO_QMETATYPE.put(Integer.class, QMetaType.Type.Int);
        JAVA_TO_QMETATYPE.put(String.class, QMetaType.Type.QString);
        JAVA_TO_QMETATYPE.put(boolean.class, QMetaType.Type.Bool);
        JAVA_TO_QMETATYPE.put(Boolean.class, QMetaType.Type.Bool);
        JAVA_TO_QMETATYPE.put(double.class, QMetaType.Type.Double);
        JAVA_TO_QMETATYPE.put(Double.class, QMetaType.Type.Double);
        JAVA_TO_QMETATYPE.put(float.class, QMetaType.Type.Float);
        JAVA_TO_QMETATYPE.put(Float.class, QMetaType.Type.Float);
        JAVA_TO_QMETATYPE.put(char.class, QMetaType.Type.QChar);
        JAVA_TO_QMETATYPE.put(Character.class, QMetaType.Type.QChar);
        for (QMetaType.Type type : QMetaType.Type.values()){
            String typeName = type.name();
            for (String pkg : QT_PACKAGES){
                String fullClassName = pkg + "." + typeName;
                try {
                    Class<?> clazz = Class.forName(fullClassName);
                    if (clazz != null)
                        JAVA_TO_QMETATYPE.put(clazz, type);
                } catch (ClassNotFoundException e) {
                    // 继续尝试下一个包
                }
            }
        }
    }

    private static void initQtContainers() {
        try {
            QT_CONTAINERS.add(Class.forName("io.qt.core.QList"));
            QT_CONTAINERS.add(Class.forName("io.qt.core.QMap"));
            QT_CONTAINERS.add(Class.forName("io.qt.core.QSet"));
            QT_CONTAINERS.add(Class.forName("io.qt.core.QHash"));
            //QT_CONTAINERS.add(Class.forName("io.qt.core.QVector"));
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("Qt容器类加载失败", e);
        }
    }

    // 类型解析部分
    public static Type create(String typeStr) {
        return parseType(typeStr.replaceAll("\\s+", ""));
    }

    private static Type parseType(String typeStr) {
        int bracketIndex = typeStr.indexOf('<');
        if (bracketIndex == -1) {
            return resolveClass(typeStr);
        }

        String rawTypeName = typeStr.substring(0, bracketIndex);
        String paramsStr = typeStr.substring(bracketIndex + 1, typeStr.lastIndexOf('>'));
        List<String> paramStrings = splitParameters(paramsStr);

        Class<?> rawType = resolveClass(rawTypeName);
        TypeVariable<?>[] typeParams = rawType.getTypeParameters();

        if (paramStrings.size() != typeParams.length) {
            throw new IllegalArgumentException("类型参数数量不匹配: " + rawTypeName);
        }

        Type[] typeArgs = new Type[paramStrings.size()];
        for (int i = 0; i < paramStrings.size(); i++) {
            typeArgs[i] = parseType(paramStrings.get(i));
        }

        return new ParameterizedTypeImpl(rawType, typeArgs, null);
    }

    private static Class<?> resolveClass(String className) {
        if (PRIMITIVE_TYPES.containsKey(className)) {
            return PRIMITIVE_TYPES.get(className);
        }

        for (String pkg : QT_PACKAGES) {
            String fullName = pkg + "." + className;
            try {
                return Class.forName(fullName);
            } catch (ClassNotFoundException ignored) {}
        }

        try {
            return Class.forName(className);
        } catch (ClassNotFoundException e) {
            throw new IllegalArgumentException("找不到类型: " + className);
        }
    }

    private static List<String> splitParameters(String paramStr) {
        List<String> params = new ArrayList<>();
        int depth = 0;
        StringBuilder buffer = new StringBuilder();

        for (char c : paramStr.toCharArray()) {
            if (c == '<') depth++;
            if (c == '>') depth--;

            if (c == ',' && depth == 0) {
                params.add(buffer.toString().trim());
                buffer.setLength(0);
            } else {
                buffer.append(c);
            }
        }

        if (buffer.length() > 0) {
            params.add(buffer.toString().trim());
        }

        return params;
    }

    // 实例创建部分
    public static <T> T createInstance(Type type) {
        return createInstance(type, new Object[0]);
    }

    public static <T> T createInstance(Type type, Object... args) {
        Class<?> clazz = getRawType(type);
        Object[] finalArgs = prepareConstructorArgs(clazz, type, args);

        try {
            Constructor<?> ctor = findMatchingConstructor(clazz, finalArgs);
            ctor.setAccessible(true);
            return (T) ctor.newInstance(finalArgs);
        } catch (Exception e) {
            throw new RuntimeException("实例创建失败: " + clazz.getName(), e);
        }
    }

    private static Class<?> getRawType(Type type) {
        if (type instanceof Class) {
            return (Class<?>) type;
        } else if (type instanceof ParameterizedType) {
            return (Class<?>) ((ParameterizedType) type).getRawType();
        }
        throw new IllegalArgumentException("不支持的Type类型: " + type.getClass());
    }

    private static Object[] prepareConstructorArgs(Class<?> clazz, Type type, Object[] args) {
        if (isQtContainer(clazz)) {
            return generateContainerMetaTypes(type);
        }
        return handleInnerClassArgs(clazz, args);
    }

    private static boolean isQtContainer(Class<?> clazz) {
        return QT_CONTAINERS.contains(clazz);
    }

    private static Object[] generateContainerMetaTypes(Type containerType) {
        List<QMetaType> metaTypes = new ArrayList<>();
        Class<?> rawType = getRawType(containerType);
        String containerName = rawType.getSimpleName();

        if (containerName.equals("QList") || containerName.equals("QVector")) {
            Type elementType = ((ParameterizedType) containerType).getActualTypeArguments()[0];
            metaTypes.add(createQMetaType(elementType));
        }
        else if (containerName.equals("QMap") || containerName.equals("QHash")) {
            ParameterizedType pt = (ParameterizedType) containerType;
            metaTypes.add(createQMetaType(pt.getActualTypeArguments()[0]));
            metaTypes.add(createQMetaType(pt.getActualTypeArguments()[1]));
        }
        else if (containerName.equals("QSet")) {
            Type elementType = ((ParameterizedType) containerType).getActualTypeArguments()[0];
            metaTypes.add(createQMetaType(elementType));
        }

        return metaTypes.toArray();
    }

    private static QMetaType createQMetaType(Type type) {
        if (type instanceof Class) {
            return basicTypeToQMetaType((Class<?>) type);
        }
        else if (type instanceof ParameterizedType) {
            ParameterizedType pt = (ParameterizedType) type;
            Class<?> containerClass = (Class<?>) pt.getRawType();
            List<QMetaType> genericTypes = Arrays.stream(pt.getActualTypeArguments())
                    .map(QType::createQMetaType)
                    .collect(Collectors.toList());

            return createContainerQMetaType(containerClass, genericTypes);
        }
        throw new IllegalArgumentException("无法处理的类型: " + type);
    }

    private static QMetaType basicTypeToQMetaType(Class<?> javaType) {
        QMetaType.Type type = JAVA_TO_QMETATYPE.getOrDefault(javaType, QMetaType.Type.UnknownType);
        if (type == QMetaType.Type.UnknownType) {
            //未找到,则默认是自定义类型
            return QMetaType.fromType(javaType);
        }
        return new QMetaType(type);
    }

    private static QMetaType createContainerQMetaType(Class<?> containerClass,
                                                      List<QMetaType> generics) {
        //优先处理Java容器
        if (Collection.class.isAssignableFrom(containerClass)) {
            return QMetaType.fromType(containerClass, generics.get(0));
        }
        if (Map.class.isAssignableFrom(containerClass)) {
            return QMetaType.fromType(containerClass, generics.get(0), generics.get(1));
        }
        String containerName = containerClass.getSimpleName();
        switch (containerName) {
            case "QList":
            //case "QVector":
                return QMetaType.fromType(QList.class, generics.get(0));
            case "QMap":
            case "QHash":
                return QMetaType.fromType(QMap.class, generics.get(0), generics.get(1));
            case "QSet":
                return QMetaType.fromType(QSet.class, generics.get(0));
            case "QPair":
                return QMetaType.fromType(QPair.class, generics.get(0), generics.get(1));
            default:
                throw new IllegalArgumentException("不支持的容器类型: " + containerName);
        }
    }

    private static Object[] handleInnerClassArgs(Class<?> clazz, Object[] args) {
        if (!clazz.isMemberClass() || Modifier.isStatic(clazz.getModifiers())) {
            return args;
        }

        try {
            Class<?> enclosingClass = clazz.getEnclosingClass();
            Object enclosingInstance = findEnclosingInstance(args, enclosingClass);
            if (enclosingInstance != null) {
                return args;
            }

            Object[] newArgs = new Object[args.length + 1];
            newArgs[0] = createInstance(enclosingClass);
            System.arraycopy(args, 0, newArgs, 1, args.length);
            return newArgs;
        } catch (Exception e) {
            throw new RuntimeException("无法创建内部类实例", e);
        }
    }

    private static Object findEnclosingInstance(Object[] args, Class<?> enclosingClass) {
        if (args.length == 0) return null;
        return Arrays.stream(args)
                .filter(arg -> arg != null && enclosingClass.isInstance(arg))
                .findFirst()
                .orElse(null);
    }

    private static Constructor<?> findMatchingConstructor(Class<?> clazz, Object[] args) {
        for (Constructor<?> ctor : clazz.getDeclaredConstructors()) {
            if (isConstructorCompatible(ctor, args)) {
                return ctor;
            }
        }
        throw new IllegalArgumentException("没有找到匹配的构造函数: " + clazz.getName());
    }

    private static boolean isConstructorCompatible(Constructor<?> ctor, Object[] args) {
        Class<?>[] paramTypes = ctor.getParameterTypes();
        if (paramTypes.length != args.length) return false;

        for (int i = 0; i < paramTypes.length; i++) {
            if (args[i] == null) {
                if (paramTypes[i].isPrimitive()) return false;
                continue;
            }

            Class<?> expected = paramTypes[i];
            Class<?> actual = args[i].getClass();

            if (!isAssignable(expected, actual)) {
                return false;
            }
        }
        return true;
    }

    private static boolean isAssignable(Class<?> target, Class<?> source) {
        if (target.isPrimitive()) {
            return isPrimitiveCompatible(target, source);
        }
        return target.isAssignableFrom(source);
    }

    private static boolean isPrimitiveCompatible(Class<?> primitiveTarget, Class<?> source) {
        Map<Class<?>, Class<?>> wrapperMap = Map.of(
                boolean.class, Boolean.class,
                byte.class, Byte.class,
                char.class, Character.class,
                short.class, Short.class,
                int.class, Integer.class,
                long.class, Long.class,
                float.class, Float.class,
                double.class, Double.class
        );
        return wrapperMap.get(primitiveTarget).isAssignableFrom(source);
    }

    // ParameterizedType实现
    private static class ParameterizedTypeImpl implements ParameterizedType {
        private final Class<?> rawType;
        private final Type[] typeArgs;
        private final Type ownerType;

        ParameterizedTypeImpl(Class<?> rawType, Type[] typeArgs, Type ownerType) {
            this.rawType = rawType;
            this.typeArgs = typeArgs.clone();
            this.ownerType = ownerType;
        }

        @Override
        public Type[] getActualTypeArguments() { return typeArgs.clone(); }

        @Override
        public Type getRawType() { return rawType; }

        @Override
        public Type getOwnerType() { return ownerType; }

        @Override
        public String toString() {
            return rawType.getName() + Arrays.stream(typeArgs)
                    .map(t -> t.getTypeName())
                    .collect(Collectors.joining(", ", "<", ">"));
        }
    }
}

测试代码

package one;

import io.qt.core.*;
import jqt.Jqt;
import jqt.QType;

import java.lang.reflect.Type;
import java.util.*;

public class Main{

    public class MyClass{
        private String name;
        private int id;
        public MyClass(){

        }
        public MyClass(String a, int b){
            name = a;
            id = b;
        }
        @Override
        public String toString(){
            return "MyClass: %1 %2".arg(name).arg(id);
        }
    }
    public static void main(String[] args){
        Jqt qt = new Jqt(args, null);
        //Type type = QType.create("QMap<String,QList<QPair<Integer,Boolean>>>");
        //Type type = QType.create("QMap<Integer,QList<QPair<Boolean,Double>>>");
        //Type type = QType.create("QHash<Integer,String>");
        //Type type = QType.create("QList<Integer>");
        //Type type = QType.create("QQueue<Integer>");
        //Type type = QType.create("QSet<Integer>");
        //Type type = QType.create("LinkedList<QDateTime>");
        //Type type = QType.create("ArrayList<Integer>");
        //Type type = QType.create("QList<LinkedList<Double>>");
        //Type type = QType.create("QList<one.Main\$MyClass>");
        Type type = QType.create("Integer");
        System.out.println(type);
        Integer x = QType.createInstance(type, 3);
        System.out.println(x);
        qt.run();
    }
}

String扩展后的测试

package one;

import io.qt.core.*;
import jqt.Jqt;

import java.util.*;

public class Main{
    public class MyClass{
        private String name;
        private int id;

        public MyClass(String a, int b){
            name = a;
            id = b;
        }
        @Override
        public String toString(){
            return "MyClass: %1 %2".arg(name).arg(id);
        }
    }
    public static void main(String[] args){
        Jqt qt = new Jqt(args, null);
        //QMap<String, QList<QPointF>> x = "QMap<String, QList<QPointF>>".create(String.class,
        //        QMetaType.fromType(QList.class, QMetaType.fromType(QPointF.class)));
        //QMap<String, QList<QPointF>> x = "QMap<String, QList<QPointF>>".create();
        //QPair<String, QPointF> x = "QPair<String, QPointF>".create("1",new QPointF(0,0));
        QList<QPair<QString, QPointF>> x = "QList<QPair<QString, QPointF>>".create();
        x.add(new QPair("1", new QPointF()));
        //QList<Integer> x = "QList<Integer>".create();
        //MyClass x = "one.Main\$MyClass".create("QtJambi",2025);
        //Double x = "Double".create(1.11);
        //ArrayList<Integer> x = "ArrayList<Integer>".create(Arrays.asList(1,2,3));
        //ArrayList<QList<Integer>> x = "ArrayList<QList<Integer>>".create();
        //QString x = "QString".create("QtJambi");
        //QList<LinkedList<Integer>> x = "QList<LinkedList<Integer>>".create(QMetaType.fromType(LinkedList.class, QMetaType.fromType(Integer.class)));
        //QList<LinkedList<Integer>> x = "QList<LinkedList<Integer>>".create();
        //HashSet<QSet<Integer>> x = "HashSet<QSet<Integer>>".create();
        //QList<MyClass> x = "QList<one.Main\$MyClass>".create();
        System.out.println(x);
        qt.run();
    }
}

 

posted on 2025-04-12 15:31  dalgleish  阅读(25)  评论(0)    收藏  举报