# eggg **Repository Path**: noear/eggg ## Basic Information - **Project Name**: eggg - **Description**: 一个 Java 类型元数据分析与构建、及流式反射调用工具(泛型、注解、提炼、别名、缓存) - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: main - **Homepage**: https://solon.noear.org/article/eggg - **GVP Project**: No ## Statistics - **Stars**: 22 - **Forks**: 3 - **Created**: 2025-10-21 - **Last Updated**: 2026-06-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: Java, generic, tool ## README

EggG

一个 Java 类型元数据分析与构建、及流式反射调用工具(泛型、注解、提炼、别名、缓存)

Ask DeepWiki Maven Apache 2 jdk-8 jdk-11 jdk-17 jdk-21 jdk-25
gitee star github star


##### 语言: 中文 | [English](README.md)
### 关于 EggG 一个 Java 类型元数据分析与构建、及流式反射调用工具。分析会涉及:类型、类、构造器、方法、字段、属性、参数,泛型传导等细节。适合一些:涉及泛型和注解的框架性项目采用。 ### 依赖包 ```xml org.noear eggg 1.1.3 ``` ### 示例 0(流式反射调用) ```java public class EgggDemo { // 一般应用内全局单例 private static Eggg eggg = new Eggg(); @Test public void case0() { // 从类开始:创建实例 -> 调用方法 String result = eggg.reflect(String.class) // result = "World" .create("Hello World") .call("substring", 6) // 调方法 .get(); // 从实例开始:直接调用 String result2 = eggg.reflect("Hello World") // result2 = "World" .call("substring", 6) // 调方法 .get(); // 字段读写 + 链式 Person person = eggg.reflect(Person.class) .create() .setField("name", "Tom") // 字段写 .setField("age", 25) // 字段写 .get(); String name = eggg.reflect(person).field("name").get(); // 字段读 -> "Tom" // 属性读写(走 getter/setter) Person p = eggg.reflect(Person.class).create() .setProperty("name", "Alice") // 走 setName .setProperty("age", 30) // 走 setAge .get(); String name = eggg.reflect(p).property("name").get(); // 走 getName -> "Alice" // 调用静态方法 String s = eggg.reflect(Person.class) .call("staticHello") .get(); // 基本类型与包装类型自动互通 Person p2 = eggg.reflect(Person.class) .create("Bob", 30) // Integer 自动匹配 int 参数 .get(); } } ``` ### 示例 1(类型元数据分析) ```java public class EgggDemo { // 一般应用内全局单例 private static Eggg eggg = new Eggg(); @Test public void case1() { Class type = new HashMap() {}.getClass(); TypeEggg typeEggg = eggg.getTypeEggg(type); if (typeEggg.isMap()) { if (typeEggg.isParameterizedType()) { // 已分析过的泛型信息 Type keyType = typeEggg.getActualTypeArguments()[0]; Type ValueType = typeEggg.getActualTypeArguments()[1]; assert keyType.equals(Integer.class); assert ValueType.equals(UserModel.class); } else { assert false; } } else { assert false; } //如果是热插拨项目,用完后可移除缓存 eggg.remove(type); } } ``` ### 示例 2(泛型嵌套传递分析) ```java public class EgggDemo { // 一般应用内全局单例 private static Eggg eggg = new Eggg(); @Test public void case2() { ClassEggg classEggg = eggg.getTypeEggg(C.class).getClassEggg(); for(FieldEggg fe : classEggg.getAllFieldEgggs()) { fe.getDigest(); } assert classEggg.getFieldEgggByName("x").getType() == List.class; assert classEggg.getFieldEgggByName("x").getTypeEggg().isParameterizedType(); assert classEggg.getFieldEgggByName("x").getTypeEggg().getActualTypeArguments()[0] == String.class; assert classEggg.getFieldEgggByName("y").getType() == Map.class; assert classEggg.getFieldEgggByName("y").getTypeEggg().isParameterizedType(); assert classEggg.getFieldEgggByName("y").getTypeEggg().getActualTypeArguments()[0] == String.class; assert classEggg.getFieldEgggByName("y").getTypeEggg().getActualTypeArguments()[1] == Integer.class; assert classEggg.getFieldEgggByName("m").getType() == String.class; assert classEggg.getFieldEgggByName("n").getType() == Integer.class; } public static class A { public X x; public Y y; } public static class B extends A, Map> { public M m; public N n; } public static class C extends B { } } ``` ### 示例 3(for Snack4) 这个示例演示如何根据注解生成提炼物、别名,以及指定构造器。需要添加定制内容。 ```java package org.noear.snack4.codec.util; import org.noear.eggg.*; import org.noear.snack4.annotation.ONodeAttrHolder; import org.noear.snack4.annotation.ONodeAttr; import org.noear.snack4.annotation.ONodeCreator; import java.lang.reflect.*; public class EgggUtil { private static final Eggg eggg = new Eggg() .withCreatorClass(ONodeCreator.class) .withDigestHandler(EgggUtil::doDigestHandle) .withAliasHandler(EgggUtil::doAliasHandle); private static String doAliasHandle(ClassEggg cw, AnnotatedEggg s, String ref) { if (s.getDigest() instanceof ONodeAttrHolder) { return ((ONodeAttrHolder) s.getDigest()).getAlias(); } else { return ref; } } private static Object doDigestHandle(ClassEggg cw, AnnotatedEggg s, Object ref) { ONodeAttr attr = s.getElement().getAnnotation(ONodeAttr.class); if (attr == null && ref != null) { return ref; } if (s instanceof FieldEggg) { return new ONodeAttrHolder(attr, ((Field) s.getElement()).getName()); } else if (s instanceof PropertyMethodEggg) { return new ONodeAttrHolder(attr, Property.resolvePropertyName(((Method) s.getElement()).getName())); } else if (s instanceof ParamEggg) { return new ONodeAttrHolder(attr, ((Parameter) s.getElement()).getName()); } else { return null; } } public static TypeEggg getTypeEggg(Type type) { return eggg.getTypeEggg(type); } } ``` ```java public class Demo { public void case1(){ TypeEggg typeEggg = EgggUtil.getTypeEggg(clazz); for (FieldEggg fw : typeEggg.getClassEggg().getFieldEgggs()) { if (fw.isStatic()) { continue; } // 已分析过的泛型 fw.getTypeEggg(); } } } ``` ### 示例 4(for Solon) ```java package org.noear.solon.core.util; import org.noear.eggg.*; import org.noear.solon.core.wrap.FieldSpec; import org.noear.solon.core.wrap.ParamSpec; import org.noear.solon.core.wrap.VarSpec; import java.lang.reflect.*; public class EgggUtil { private static final Eggg eggg = new Eggg() .withAliasHandler(EgggUtil::doAliasHandle) .withDigestHandler(EgggUtil::doDigestHandle) .withReflectHandler(new EgggReflectHandler()); private static String doAliasHandle(ClassEggg cw, AnnotatedEggg s, String ref) { if (s.getDigest() instanceof VarSpec) { return s.getDigest().getName(); } return ref; } private static Object doDigestHandle(ClassEggg cw, AnnotatedEggg s, Object ref) { if (s instanceof FieldEggg) { return new FieldSpec((FieldEggg) s); } else if (s instanceof ParamEggg) { return new ParamSpec((ParamEggg) s); } return ref; } public static TypeEggg getTypeEggg(Type type) { return eggg.getTypeEggg(type); } public static ClassEggg getClassEggg(Type type) { return getTypeEggg(type).getClassEggg(); } } ```