基于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(); } }
浙公网安备 33010602011771号