具体来说,动态上下文的诸多行为会依赖于一个动态工厂,此注解即应用于一个字段或者局部变量,亦或者是一个方法参数之上,其上下文语义与java变量,字段和方法参数无异, 10 | * 请注意,当注解用于java静态字段时,此标记同样会具有静态上下文,反之亦然,即您不能在静态上下文内访问非静态上下文工厂标识 11 | * 12 | *
对于同一个上下文内的多次设置上下文标记,则在访问动态工厂时,会选择在此之前的最后一个标记使用*/ 13 | @Retention(RetentionPolicy.SOURCE) 14 | @Target({ElementType.FIELD, ElementType.LOCAL_VARIABLE, ElementType.PARAMETER}) 15 | public @interface ContextMaker { 16 | } 17 | -------------------------------------------------------------------------------- /annotations/src/main/java/dynamilize/annotations/DynamicContext.java: -------------------------------------------------------------------------------- 1 | package dynamilize.annotations; 2 | 3 | import dynamilize.DynamicClass; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | /**动态上下文标记,携带此注解的类型会被视为一个具有动态化语义的上下文 11 | *
具体来说,这个注解是类型内局部动态语义的最外层标记,所有局部动态语义声明的注解都需要其所在的环境具有此注解标记的外层 12 | *
本注解本身没有实际作用,关于这个注解支持的局部语义注解可参见:: 13 | *
具体来说,一个具备此注解的类,其中声明的各种方法语句的上下文都会被调整为适配到{@link DynamicClass#visitClass(Class, JavaHandleHelper)}的语义, 14 | * 并保存其对应的动态类型对象及名称。该注解并不会递归的处理被标记类中的内部类,但是被标记的类中不能有任何非静态的内部类 15 | *
此标记转换的动态类类名由DynamilizeClass.{@link DynamilizeClass#className()}给出,默认使用标记的类类名,细节请参阅这个注解属性
16 | *
17 | *
18 | *
19 | *
警告:此注解转换的动态类型标记可能并不能可靠的加载,在您使用这个注解生成的动态类之前,请通过调用类的任意字段/方法来确保此类型已加载
20 | *特别注意,在注解{@link NewDynamic}中传递该类的NAME常量并不能使jvm加载这个类,因为NAME会被转化为常量提供给注解参数, 21 | * 因此在通过上下文注解引用的该动态类并不能可靠的加载此动态类
22 | *以下是注解的工作细节: 25 | *
此外,被标记为动态类型记录的类也可以扩展一个动态类型记录,这会对INSTANCE字段的初始化产生影响,具体来说,初始化语句都是调用{@link DynamicClass#visit(String, Class, DynamicClass, JavaHandleHelper)} 41 | * 来直接获取动态类型实例,而扩展会影响的就是其最后一个参数,直观来看
{@code 42 | * //一个没有扩展的动态类型记录中,INSTANCE的等价初始化语句是这样的: 43 | * public static final DynamicClass INSTANCE = DynamicClass.visit(NAME,47 | * 值得关注的是其中的字段{@code $helper$},这个字段是保存用于访问java类使用的辅助器的静态字段, 48 | * 您同样必须在原始的类型定义中创建指定名称的java静态字段,否则将无法通过编译,关于选择这个字段的细节,请参阅DynamilizeClass.{@link DynamilizeClass#helperField()} 49 | * 50 | *.class, null, $helper$); 44 | * //而有扩展一个父类的动态类型记录中,INSTANCE的等价初始化语句是这样的: 45 | * public static final DynamicClass INSTANCE = DynamicClass.visit(NAME, .class, .INSTANCE, $helper$); 46 | * }
另外,在您使用这个注解标记类型时,将类型标记为abstract并实现{@link DynamilizedClass}接口是一种不错的选择,该接口包含了INSTANCE字段和NAME字段,
51 | * 这是一种魔法操作,例如,在java中,您可以直接对被标记的类调用INSTANCE字段和NAME字段,但这是通过类转移的调用,实际上会指向{@link DynamilizedClass}接口的字段,
52 | * 但是在注解处理后,被标记类中会被添加这两个字段,从外部访问这个类型的INSTANCE和NAME字段的目标就会被确定而非重定向到DynamilizedClass接口,
53 | * 具体细节请参阅{@link DynamilizedClass}*/
54 | @Retention(RetentionPolicy.SOURCE)
55 | @Target(ElementType.TYPE)
56 | public @interface DynamilizeClass {
57 | /**应用于动态类的名称,这会为此类的NAME字段设置值,默认在不设置这个名称的情况下,注解处理器会使用被标记的类的完整类名作为该动态类的名称*/
58 | String className() default " 您可以根据需要设置此选项,假如内存性能十分重要,则推荐设为false,否则通常来说设为true都能提升时间性能,尤其是在动态类型多次扩展嵌套的情况下*/
65 | boolean signatureMethods() default true;
66 |
67 | /**辅助类型动态声明的魔法接口,通常在您对一个类型标记为{@link DynamilizeClass}时,建议将类型设置为abstract并添加实现此接口
68 | * 接口扩展自{@link DynamicObject},以便在您描述类型行为时可以直接使用动态对象的方法,值得注意的是,
69 | * 您在此上下文中调用属于{@link DynamicObject}的API是不会被再次转化为动态调用动态方法的,即这些API会被注解处理器略过,仅仅将调用对象重定向到self参数
70 | * 此外,该接口中定义了两个常量字段和一个方法,字段用作在java语义中直接引用该类型的INSTANCE字段和NAME字段,在经过注解处理器处理后这两个字段不会被重定向到该接口。
71 | * 方法{@link DynamilizedClass#super$()}则是对动态super指针的虚拟引用,以便您可以以动态描述的方法那样调用super池的行为,对这个方法的调用在注解处理后会被转化为对sup参数的引用*/
72 | interface DynamilizedClass 具体来讲,此注解的作用即将形如 实例化动态代理对象声明的参数从注解的属性内提供,此注解的参数:
17 | * 另外,如果您声明的变量类型是{@link dynamilize.DynamicObject},同时将右侧表达式添加类型转换到DynamicObject,此时生成的语句将直接获取原始的动态对象,
38 | * 而不调用其{@code objSelf()}方法,举例来说,假设:
39 | * 关于此注解的作用细节,请参阅本注解的参数说明*/
49 | @Retention(RetentionPolicy.SOURCE)
50 | @Target({ElementType.FIELD, ElementType.LOCAL_VARIABLE})
51 | public @interface NewDynamic {
52 | /**创建动态对象使用的{@linkplain dynamilize.DynamicMaker 动态工厂}引用语句,这会直接被整合为一段java语句插入到newInstance调用中,
53 | * 默认使用动态上下文中被标记的动态工厂,并且通常情况下也不推荐设置直接引用语句*/
54 | String refDynamicMaker() default " 此类行为可能完全打破模块化的访问保护,本身是不安全的,若不是必要情况,请尽量避免使用该类
13 | * 此类仅在JDK9之后可用,避免在更早的版本引用此类的方法,且此类仅在desktop平台可用,安卓平台不可使用此类的任何行为
14 | *
15 | * @author EBwilson */
16 | @SuppressWarnings({"unchecked"})
17 | public class Demodulator{
18 | private static final long fieldFilterOffset = 112L;
19 |
20 | private static final Unsafe unsafe;
21 |
22 | private static final Field opensField;
23 | private static final Field exportField;
24 |
25 | private static final Method exportNative;
26 |
27 | static{
28 | try{
29 | Constructor 方法入口的运行实际上是对样版方法的引用,因此需要确保样版方法所在的类始终有效,方法入口会生成这个方法的入口函数提供给动态对象使用
8 | *
9 | * @author EBwilson */
10 | @SuppressWarnings("unchecked")
11 | public class JavaMethodEntry implements IFunctionEntry{
12 | private final String name;
13 | private final FunctionType type;
14 | private final Function, ?> defFunc;
15 |
16 | /**直接通过目标方法创建方法入口,并生成对方法引用的句柄提供给匿名函数以描述此函数行为
17 | *
18 | * @param invokeMethod 样版方法*/
19 | public JavaMethodEntry(Method invokeMethod){
20 | this.name = invokeMethod.getName();
21 | this.type = FunctionType.inst(invokeMethod);
22 |
23 | defFunc = (self, args) -> {
24 | try {
25 | return invokeMethod.invoke(self.objSelf(), args.args());
26 | } catch (InvocationTargetException|IllegalAccessException e) {
27 | throw new RuntimeException(e);
28 | }
29 | };
30 | }
31 |
32 | @Override
33 | public String getName(){
34 | return name;
35 | }
36 |
37 | @Override
38 | public 参数表对象为可复用对象,引用完毕后请使用{@link ArgumentList#recycle()}回收对象以减少堆内存更新频率
8 | *
9 | * @author EBwilson */
10 | public class ArgumentList{
11 | public static int MAX_INSTANCE_STACK = 2048;
12 |
13 | public static final Stack 对于一个{@linkplain DynamicClass 动态类}的实例,实例的数据池一定会有一个父池,这个池以动态类的直接超类描述的信息进行初始化。
7 | * 访问池信息无论如何都是以最近原则,即若本池内没有找到数据,则以距离实例的池最近的具有此变量/函数的父池的数据为准
8 | *
9 | * @author EBwilson*/
10 | @SuppressWarnings({"unchecked"})
11 | public class DataPool{
12 | private static final String init = " 通常来说你不应该在{@link DynamicMaker}之外的任何地方实例化此类型
27 | *
28 | * @param superPool 此池的父池*/
29 | public DataPool(DataPool superPool){
30 | this.superPool = superPool;
31 | }
32 |
33 | public void init(DynamicObject> self, Object... args){
34 | DynamicClass curr = self.getDyClass();
35 | HashSet 函数的名称,行为与参数类型和java方法保持一致,返回值由行为传入的匿名函数确定,例如:
69 | * 如果函数没有被定义则返回空
122 | *
123 | * @param name 函数的名称
124 | * @param type 函数的参数类型
125 | * @return 选中函数的函数入口*/
126 | public IFunctionEntry select(String name, FunctionType type){
127 | Map 实施时应当按方法的功能说明针对运行平台进行实现。
8 | *
9 | * @author EBwilson */
10 | public interface JavaHandleHelper{
11 | void makeAccess(Object object);
12 |
13 | IVariable genJavaVariableRef(Field field);
14 |
15 | IFunctionEntry genJavaMethodRef(Method method);
16 | }
17 |
--------------------------------------------------------------------------------
/core/src/main/java/dynamilize/PackageAccHandler.java:
--------------------------------------------------------------------------------
1 | package dynamilize;
2 |
3 | import dynamilize.classmaker.ClassInfo;
4 | import dynamilize.classmaker.CodeBlock;
5 | import dynamilize.classmaker.Parameter;
6 | import dynamilize.classmaker.code.IClass;
7 | import dynamilize.classmaker.code.ILocal;
8 | import dynamilize.classmaker.code.IMethod;
9 |
10 | import java.lang.reflect.Constructor;
11 | import java.lang.reflect.Method;
12 | import java.lang.reflect.Modifier;
13 | import java.util.Arrays;
14 | import java.util.HashMap;
15 | import java.util.Map;
16 |
17 | /**包私有方法访问提升使用的工具类,该类用于对一个目标类创建一串用于提升包私有方法的继承子树,以达到对包私有方法进行重写的目的
18 | * 直观的说,这个类做的事情如下:
23 | * 通过此工具创建的代理实例会将所有可用(非static/final/private/package private)方法调用转入代理调用处理器,在此工具中被声明为了{@link ProxyMaker#invoke(DynamicObject, FuncMarker, FuncMarker, ArgumentList)}])}。
11 | * 使用此工具时需要给出一个{@link DynamicMaker}用于构建动态代理实例,尽管可能你需要的只是具备代理行为的{@linkplain DynamicClass 动态类型}。
12 | * 另外,动态类型中声明的函数也会被代理拦截,作用时机与动态类实例化的行为影响是一致的,请参阅{@link DynamicClass 动态类型函数变更的作用时机}
13 | * 你可以使用lambda表达式引用{@link ProxyMaker#getDefault(DynamicMaker, ProxyHandler)}获取默认的lambda实现,
14 | * 或者实现此类的抽象方法{@link ProxyMaker#invoke(DynamicObject, FuncMarker, FuncMarker, ArgumentList)}。
15 | * 默认实现调用会传入给出的匿名函数,否则子类应当按需要的代理处理方式实现此方法
152 | *
153 | * @param proxy 动态代理实例
154 | * @param method 被拦截的方法
155 | * @param args 实参列表
156 | *
157 | * @return 返回值*/
158 | protected abstract Object invoke(DynamicObject> proxy, FuncMarker method, FuncMarker proxiedMethod, ArgumentList args);
159 |
160 | /**异常处理器,当代理运行中发生任何异常都会转入此方法进行处理,默认直接封装为RuntimeException抛出
161 | *
162 | * @param thr 运行过程中捕获的异常*/
163 | public void throwException(Throwable thr){
164 | throw new RuntimeException(thr);
165 | }
166 |
167 | public static class FunctionMarker implements FuncMarker{
168 | public static int maxPoolSize = 4096;
169 |
170 | private static FunctionMarker[] pool = new FunctionMarker[128];
171 | private static int cursor = -1;
172 |
173 | private String name;
174 | private FunctionType type;
175 | private IFunctionEntry entry;
176 | private Function, Object> function;
177 |
178 | private static FunctionMarker make(IFunctionEntry functionEntry){
179 | FunctionMarker res = cursor < 0? new FunctionMarker(): pool[cursor];
180 |
181 | res.name = functionEntry.getName();
182 | res.type = functionEntry.getType();
183 | res.entry = functionEntry;
184 | res.function = functionEntry.getFunction();
185 |
186 | return res;
187 | }
188 |
189 | @Override
190 | public String getName(){
191 | return entry.getName();
192 | }
193 |
194 | @Override
195 | public FunctionType getType(){
196 | return entry.getType();
197 | }
198 |
199 | @Override
200 | @SuppressWarnings({"unchecked", "rawtypes"})
201 | public Object invoke(DynamicObject> self, ArgumentList args){
202 | return function.invoke((DynamicObject) self, args);
203 | }
204 |
205 | @Override
206 | public String toString(){
207 | return "function: " + name + type;
208 | }
209 |
210 | private void recycle(){
211 | name = null;
212 | type = null;
213 | function = null;
214 | entry = null;
215 |
216 | if (cursor >= maxPoolSize) return;
217 |
218 | cursor++;
219 | if (cursor >= pool.length){
220 | pool = Arrays.copyOf(pool, pool.length*2);
221 | }
222 |
223 | pool[cursor] = this;
224 | }
225 | }
226 |
227 | /**调用封装器,提供了一个方法{@link FuncMarker#invoke(DynamicObject, ArgumentList)}方法来直接调用这个对象封装的方法或者函数*/
228 | public interface FuncMarker {
229 | default String signature(){
230 | return FunctionType.signature(getName(), getType());
231 | }
232 |
233 | String getName();
234 |
235 | FunctionType getType();
236 |
237 | Object invoke(DynamicObject> self, ArgumentList args);
238 |
239 | default Object invoke(DynamicObject> self, Object... args){
240 | ArgumentList lis = ArgumentList.as(args);
241 | Object r = invoke(self, lis);
242 | lis.type().recycle();
243 | lis.recycle();
244 | return r;
245 | }
246 |
247 | default Object invoke(DynamicObject> self, FunctionType type, Object... args){
248 | ArgumentList lis = ArgumentList.asWithType(type, args);
249 | Object r = invoke(self, lis);
250 | lis.recycle();
251 | return r;
252 | }
253 | }
254 |
255 | public interface ProxyHandler{
256 | Object invoke(DynamicObject> proxy, FuncMarker func, FuncMarker superFunction, ArgumentList args);
257 | }
258 | }
259 |
--------------------------------------------------------------------------------
/core/src/main/java/dynamilize/Variable.java:
--------------------------------------------------------------------------------
1 | package dynamilize;
2 |
3 | public class Variable implements IVariable{
4 | private final String name;
5 | private final Initializer> init;
6 |
7 | public Variable(String name){
8 | this.name = name;
9 | this.init = null;
10 | }
11 |
12 | public Variable(String name, Initializer> init){
13 | this.name = name;
14 | this.init = init;
15 | }
16 |
17 | @Override
18 | public String name(){
19 | return name;
20 | }
21 |
22 | @Override
23 | public void init(DynamicObject> object) {
24 | Object value = init == null? null: init.getInit();
25 | if (value == null) return;
26 | if (value.getClass().isPrimitive()){
27 | if (value instanceof Byte b) set(object, b.byteValue());
28 | else if (value instanceof Short b) set(object, b.shortValue());
29 | else if (value instanceof Integer b) set(object, b.intValue());
30 | else if (value instanceof Character b) set(object, b.charValue());
31 | else if (value instanceof Long b) set(object, b.longValue());
32 | else if (value instanceof Float b) set(object, b.floatValue());
33 | else if (value instanceof Double b) set(object, b.doubleValue());
34 | else if (value instanceof Boolean b) set(object, b.booleanValue());
35 | else throw new IllegalHandleException("how do you cased this?");
36 | }
37 | else set(object, value);
38 | }
39 |
40 | @Override
41 | public
8 | * 对于一个包装动态对象,仅能动态的访问其原有的属性和方法,以下行为将抛出异常:
9 | * 特别的,对于基本数据类型:
49 | *
实例化变量的动态化语句标志,用于声明一个java语义的动态对象实例化语句
10 | * {@code
11 | * [modifiers] Type variableName = new Type(
的语句转换为创建一个动态代理对象,这可以是字段声明,亦可以是方法中的局部变量声明,其中等号右侧必须是一个new语句。
13 | *
注意,右侧的new语句不得携带匿名扩展块,在未来的更新中可能会添加对此的支持
14 | *
假如您实例化的是一个非静态内部类,形如{@code outer.new Inner(
18 | *
23 | * 使用上述的参数,此注解会将一个满足条件的语句变换为创建动态对象,例如:
24 | * {@code
25 | * //假设,在上文已经标记了一个动态工厂"maker"
26 | * @NewDynamic(dynClassName = "SampleDyc", impls = {Collection.class, Runnable.class})
27 | * Object dyObj = new Object();
28 | * }
29 | * 那么,经过处理编译后的等效代码是这样的:
30 | * {@code
31 | * Object dyObj = maker.newInstance(Object.class, new Class>[]{Collection.class, Runnable.class}, (Class>[])null, DynamicClass.get("SampleDyc")).objSelf();
32 | * }
33 | * 如果在new调用构造函数时有传入参数,参数会正确的添加在上述的语句最后一个参数处。一个比较特殊的地方在于,为了内存性能,
34 | * 您传递的接口列表(额外接口和切面接口)都会被处理为一个存在于类中的静态常量以供重复调用,对于列表接口类型相同的一组接口会复用同一个常量接口表
35 | *
36 | *
37 | * {@code
40 | * @NewDynamic(dynClassName = "SampleDyc", impls = {Collection.class, Runnable.class})
41 | * DynamicObject
43 | * 那么,经过处理编译后的等效代码是这样的:
44 | * {@code
45 | * DynamicObject
47 | * 简单来说这个注解的作用就是让您更便捷的使用java语句创建一个动态代理对象,而不需要使用maker的{@code newInstance(...)}方法
48 | * {@code
31 | * new DynamicFactory().setDefaultGenerator().setDefaultHelper().getMaker();
32 | * }
33 | *
34 | * @see DynamicFactory#setDefaultGenerator()
35 | * @see DynamicFactory#setDefaultHelper()
36 | * @return 一个由默认声明生产的动态生成器*/
37 | public static DynamicMaker getDefault(){
38 | return DEFAULT.getMaker();
39 | }
40 |
41 | /**获取{@linkplain DynamicMaker 动态生成器}实例
42 | *
43 | * @throws NullPointerException 若有必要的属性尚未设置*/
44 | public DynamicMaker getMaker(){
45 | PackageAccHandler handler = this.handler;
46 |
47 | AbstractClassGenerator generator = this.generator;
48 |
49 | Objects.requireNonNull(helper);
50 | Objects.requireNonNull(generator);
51 |
52 | return handler == null? new DynamicMaker(helper) {
53 | @Override
54 | protected Function getFunction(){
39 | return (Function) defFunc;
40 | }
41 |
42 | @Override
43 | public FunctionType getType(){
44 | return type;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/baseimpl/src/main/java/dynamilize/JavaVariable.java:
--------------------------------------------------------------------------------
1 | package dynamilize;
2 |
3 | import java.lang.invoke.MethodHandle;
4 | import java.lang.invoke.MethodHandles;
5 | import java.lang.reflect.Field;
6 |
7 | /**对java字段的引用对象,基于{@linkplain MethodHandle 方法句柄}的默认内部实现
8 | *
9 | * @author EBwilson */
10 | public class JavaVariable implements IVariable{
11 | private final Field field;
12 |
13 | private final MethodHandle getter;
14 | private final MethodHandle setter;
15 |
16 | private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
17 |
18 | public JavaVariable(Field field){
19 | this.field = field;
20 |
21 | try {
22 | getter = LOOKUP.unreflectGetter(field);
23 | setter = LOOKUP.unreflectSetter(field);
24 | } catch (IllegalAccessException e) {
25 | throw new RuntimeException(e);
26 | }
27 | }
28 |
29 | @Override
30 | public String name(){
31 | return field.getName();
32 | }
33 |
34 | @Override
35 | public void init(DynamicObject> object) { /*no action*/ }
36 |
37 | @SuppressWarnings("unchecked")
38 | @Override
39 | public {@code
70 | * java定义的方法
71 | * int getTime(String location){
72 | * return foo(location);
73 | * }
74 | * 等价于设置函数
75 | * set("getTime", (self, args) -> return foo(args.get(0)), String.class);
76 | * }
77 | *
78 | * @param name 函数名称
79 | * @param argsType 函数的参数类型列表
80 | * @param function 描述此函数行为的匿名函数*/
81 | public void setFunction(String name, Function, ?> function, Class>... argsType){
82 | FunctionType type = FunctionType.inst(argsType);
83 | funcPool.computeIfAbsent(name, n -> new HashMap<>())
84 | .put(type, new FunctionEntry<>(name, function, type));
85 | }
86 |
87 | public func, Class>[] argTypes){
88 | FunctionType type = FunctionType.inst(argTypes);
89 | funcPool.computeIfAbsent(name, n -> new HashMap<>())
90 | .put(type, new FunctionEntry<>(name, func, type, this));
91 | }
92 |
93 | public void setFunction(IFunctionEntry functionEntry){
94 | funcPool.computeIfAbsent(functionEntry.getName(), e -> new HashMap<>()).put(functionEntry.getType(), functionEntry);
95 | }
96 |
97 | /**从类层次结构中获取变量的对象
98 | *
99 | * @param name 变量名
100 | * @return 变量对象*/
101 | public IVariable getVariable(String name){
102 | IVariable var = varPool.get(name);
103 | if(var != null) return var;
104 |
105 | if(superPool != null){
106 | return superPool.getVariable(name);
107 | }
108 |
109 | return null;
110 | }
111 |
112 | /**向池中添加一个变量对象,一般来说仅在标记java字段作为变量时会用到
113 | *
114 | * @param var 加入池的变量*/
115 | public void setVariable(IVariable var){
116 | varPool.putIfAbsent(var.name(), var);
117 | }
118 |
119 | /**将类层次结构中定义的函数输出为函数入口,会优先查找类型签名相同的函数,若未查找到相同的才会转入类型签名匹配的函数,
120 | * 因此调用函数在性能需求较高的情况下,建议对实参列表明确声明类型的签名,这可以有效提高重载决策的速度
121 | * ReadOnlyPool getReader(DynamicObject owner){
175 | return new ReadOnlyPool(this, owner, null);
176 | }
177 |
178 | public {
5 | R invoke(DynamicObject self, ArgumentList args);
6 |
7 | default R invoke(DynamicObject self, Object... args){
8 | ArgumentList lis = ArgumentList.as(args);
9 | R r = invoke(self, lis);
10 | lis.type().recycle();
11 | lis.recycle();
12 | return r;
13 | }
14 |
15 | default R invoke(DynamicObject self, FunctionType type, Object... args){
16 | ArgumentList lis = ArgumentList.asWithType(type, args);
17 | R r = invoke(self, lis);
18 | lis.recycle();
19 | return r;
20 | }
21 |
22 | interface NonRetFunction{
23 | void invoke(DynamicObject self, ArgumentList args);
24 | }
25 |
26 | interface SuperGetFunction{
27 | R invoke(DynamicObject self, DataPool.ReadOnlyPool superPointer, ArgumentList args);
28 | }
29 |
30 | interface NonRetSuperGetFunc{
31 | void invoke(DynamicObject self, DataPool.ReadOnlyPool superPointer, ArgumentList args);
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/core/src/main/java/dynamilize/FunctionEntry.java:
--------------------------------------------------------------------------------
1 | package dynamilize;
2 |
3 |
4 | public class FunctionEntry implements IFunctionEntry{
5 | private final String name;
6 | private final Function func;
7 | private final FunctionType type;
8 |
9 | public FunctionEntry(String name, Function func, FunctionType type){
10 | this.name = name;
11 | this.func = func;
12 | this.type = type;
13 | }
14 |
15 | public FunctionEntry(String name, Function.SuperGetFunction func, FunctionType type, DataPool owner){
16 | this(
17 | name,
18 | (s, a) -> {
19 | DataPool.ReadOnlyPool p = owner.getSuper(s, s.baseSuperPointer());
20 | R res = func.invoke(s, p, a);
21 | p.recycle();
22 | return res;
23 | },
24 | type
25 | );
26 | }
27 |
28 | @Override
29 | public String getName(){
30 | return name;
31 | }
32 |
33 | @Override
34 | @SuppressWarnings("unchecked")
35 | public Function getFunction(){
36 | return func;
37 | }
38 |
39 | @Override
40 | public FunctionType getType(){
41 | return type;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/core/src/main/java/dynamilize/FunctionType.java:
--------------------------------------------------------------------------------
1 | package dynamilize;
2 |
3 | import dynamilize.classmaker.ClassInfo;
4 |
5 | import java.lang.invoke.MethodType;
6 | import java.lang.reflect.Executable;
7 | import java.lang.reflect.Method;
8 | import java.util.Arrays;
9 | import java.util.List;
10 | import java.util.Stack;
11 |
12 | /**函数类型封装对象,记录函数的参数类型用于比对和搜索函数
13 | *
14 | * @author EBwilson */
15 | public class FunctionType{
16 | /**复用回收区容量,改数值通常不需要设置,但如果您可能需要大规模的递归或大量的并发调用,那么您可能需要将这个限制设置为一个更高的数值*/
17 | public static int MAX_RECYCLE = 4096;
18 |
19 | private static final Class>[] EMPTY = new Class[0];
20 | private static final Stack Function getFunction();
13 |
14 | /**获取此方法的形式参数表类型*/
15 | FunctionType getType();
16 | }
17 |
--------------------------------------------------------------------------------
/core/src/main/java/dynamilize/IVariable.java:
--------------------------------------------------------------------------------
1 | package dynamilize;
2 |
3 | public interface IVariable{
4 | String name();
5 |
6 | void init(DynamicObject> object);
7 |
具体来说,将目标基类传入{@link PackageAccHandler#handle(Class)}方法以后,会依次检查此类型的,每一个父类型中是否存在包私有的方法,
19 | * 若存在包私有方法,那么就会使用这个类的包名对上一层类型继承一次,通过{@link PackageAccHandler#loadClass(ClassInfo, Class)}将这个类加载到同一保护域,
20 | * 此时,此次继承类型即可访问目标类包私有方法,重写并将其访问修饰符提升为{@code protected},如此完成对基类所有超类的遍历后即可访问所有该类层次结构中的包私有方法
21 | *
22 | * {@code
24 | * 假设有下面几个类:
25 | *
26 | * package pac1;
27 | * public class A{
28 | * void method1(){ //包私有方法
29 | *
30 | * }
31 | *
32 | * public void test(){
33 | * method1();
34 | * }
35 | * }
36 | *
37 | * package pac2;
38 | * import pac1.A;
39 | * public class B extends A{
40 | * void method2(){ //包私有方法
41 | *
42 | * }
43 | *
44 | * @Override
45 | * public void test(){
46 | * super.test();
47 | * method2();
48 | * }
49 | * }
50 | *
51 | * 如果对handle方法传入B类,那么会创建如下两个类型:
52 | *
53 | * package pac2:
54 | * public class B$packageAccess$0 extends B{
55 | * @Override
56 | * protected void method2(){
57 | * super.method2();
58 | * }
59 | * }
60 | *
61 | * package pac1:
62 | * import pac2.B$packageAccess$0;
63 | * public class A$packageAccess$0 extends B$packageAccess$0{
64 | * @Override
65 | * protected void method1(){
66 | * super.method2();
67 | * }
68 | * }
69 | *
70 | * 最后handle方法会将类对象pac1.A$packageAccess$0返回,此时,所有包私有方法都已被提升为protected,其子类对两个包私有方法的重写,在调用test方法时都会生效
71 | * }
72 | * 注意:
73 | *
76 | *
77 | * @author EBwilson
78 | * @since 1.6*/
79 | @SuppressWarnings("unchecked")
80 | public abstract class PackageAccHandler {
81 | public static final int PAC_PRI_FLAGS = Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL;
82 | public static final ILocal[] A = new ILocal[0];
83 | private final Map{@code
16 | * 一个简单的用例:
17 | * ArrayList list = ProxyMaker.getDefault(DynamicMaker.getDefault(), (self, method, args) -> {
18 | * System.out.println(method);
19 | * return method.invoke(self, args);
20 | * }).newProxyInstance(ArrayList.class).self();
21 | *
22 | * 这个list的所有可用方法在执行时都将会打印方法本身的签名
23 | * }
24 | *
25 | * @since 1.2
26 | * @author EBwilson */
27 | public abstract class ProxyMaker{
28 | private static final Map
10 | *
*/
14 | public class WrappedObject void setFunction(String name, Function func, Class>... argTypes)
21 | { throw new IllegalHandleException("wrapped object class is immutable"); }
22 |
23 | @Override
24 | public void visitClass(Class> template, JavaHandleHelper helper)
25 | { throw new IllegalHandleException("wrapped object class is immutable"); }
26 |
27 | @Override
28 | public void visitField(Field field)
29 | { throw new IllegalHandleException("wrapped object class is immutable"); }
30 |
31 | @Override
32 | public void visitMethod(Method method, JavaHandleHelper helper)
33 | { throw new IllegalHandleException("wrapped object class is immutable"); }
34 | };
35 |
36 | private final DataPool pool;
37 | private final T obj;
38 |
39 | WrappedObject(T obj, DataPool pool) {
40 | this.pool = pool;
41 | this.obj = obj;
42 | }
43 |
44 | @SuppressWarnings("unchecked")
45 | @Override
46 | public T objSelf() {
47 | return obj;
48 | }
49 |
50 | @Override
51 | public DynamicClass getDyClass() {
52 | return $wrappedDef$;
53 | }
54 |
55 | @Override
56 | public IVariable getVariable(String name) {
57 | return pool.getVariable(name);
58 | }
59 |
60 | @Override
61 | public DataPool.ReadOnlyPool baseSuperPointer() {
62 | return null;
63 | }
64 |
65 | @Override
66 | public void setVariable(IVariable variable) {
67 | throw new IllegalHandleException("wrapped object cannot add new variable");
68 | }
69 |
70 | @Override
71 | public extends AnnotatedMember implements IMethod{
17 | private final CodeBlock owner;
20 |
21 | IClass owner, int modifiers, String name, IClass owner(){
59 | return owner;
60 | }
61 |
62 | @Override
63 | public String typeDescription(){
64 | StringBuilder builder = new StringBuilder();
65 | builder.append("(");
66 | for(IClass> arg: parameter.stream().map(Parameter::getType).toArray(IClass[]::new)){
67 | builder.append(arg.realName());
68 | }
69 |
70 | return builder + ")" + returnType.realName();
71 | }
72 |
73 | @Override
74 | public IClass{@code
50 | * int -> I
51 | * float -> F
52 | * byte -> B
53 | * short -> S
54 | * long -> J
55 | * double -> D
56 | * char -> C
57 | * boolean -> Z
58 | * void -> V
59 | * }
60 | *
61 | * @return 类的实际名称*/
62 | String realName();
63 |
64 | /**获取此类型的字节码类型标识符,即真实名称省去首位的符号L,例如java.lang.Object -> java/lang/Object
65 | *
66 | * @return 类型的字节标识名称
67 | * @see ClassInfo#realName() */
68 | String internalName();
69 |
70 | int modifiers();
71 |
72 | IClass super T> superClass();
73 |
74 | List