on(Class.forName(name))
42 | *
43 | * @param name
44 | * 完整类名
45 | * @return 工具类自身
46 | * @throws ReflectException
47 | * 反射时发生的异常
48 | * @see #on(Class)
49 | */
50 | public static Reflect on(String name) throws ReflectException {
51 | return on(forName(name));
52 | }
53 |
54 | /**
55 | * 封装Class.forName(name)
56 | *
57 | * 可以这样调用: on(Xxx.class)
58 | *
59 | * @param clazz
60 | * 类
61 | * @return 工具类自身
62 | * @throws ReflectException
63 | * 反射时发生的异常
64 | * @see #on(Class)
65 | */
66 | public static Reflect on(Class> clazz) {
67 | return new Reflect(clazz);
68 | }
69 |
70 | /**
71 | * 包装起一个对象
72 | *
73 | * 当你需要访问实例的字段和方法时可以使用此方法 {@link Object}
74 | *
75 | * @param object
76 | * 需要被包装的对象
77 | * @return 工具类自身
78 | */
79 | public static Reflect on(Object object) {
80 | return new Reflect(object);
81 | }
82 |
83 | /**
84 | * 使受访问权限限制的对象转为不受限制。 一般情况下, 一个类的私有字段和方法是无法获取和调用的, 原因在于调用前Java会检查是否具有可访问权限,
85 | * 当调用此方法后, 访问权限检查机制将被关闭。
86 | *
87 | * @param accessible
88 | * 受访问限制的对象
89 | * @return 不受访问限制的对象
90 | */
91 | public static call(name, new Object[0])
261 | *
262 | * @param name
263 | * 方法名
264 | * @return 工具类自身
265 | * @throws ReflectException
266 | * @see #call(String, Object...)
267 | */
268 | public Reflect call(String name) throws ReflectException {
269 | return call(name, new Object[0]);
270 | }
271 |
272 | /**
273 | * 给定方法名和参数,调用一个方法。
274 | *
275 | * 封装自 {@link java.lang.reflect.Method#invoke(Object, Object...)}, 可以接受基本类型
276 | *
277 | * @param name
278 | * 方法名
279 | * @param args
280 | * 方法参数
281 | * @return 工具类自身
282 | * @throws ReflectException
283 | */
284 | public Reflect call(String name, Object... args) throws ReflectException {
285 | Class>[] types = types(args);
286 |
287 | // 尝试调用方法
288 | try {
289 | Method method = exactMethod(name, types);
290 | return on(method, object, args);
291 | }
292 |
293 | // 如果没有符合参数的方法,
294 | // 则匹配一个与方法名最接近的方法。
295 | catch (NoSuchMethodException e) {
296 | try {
297 | Method method = similarMethod(name, types);
298 | return on(method, object, args);
299 | } catch (NoSuchMethodException e1) {
300 |
301 | throw new ReflectException(e1);
302 | }
303 | }
304 | }
305 |
306 | /**
307 | * 根据方法名和方法参数得到该方法。
308 | */
309 | private Method exactMethod(String name, Class>[] types)
310 | throws NoSuchMethodException {
311 | Class> type = type();
312 |
313 | // 先尝试直接调用
314 | try {
315 | return type.getMethod(name, types);
316 | }
317 |
318 | // 也许这是一个私有方法
319 | catch (NoSuchMethodException e) {
320 | do {
321 | try {
322 | return type.getDeclaredMethod(name, types);
323 | } catch (NoSuchMethodException ignore) {
324 | }
325 |
326 | type = type.getSuperclass();
327 | } while (type != null);
328 |
329 | throw new NoSuchMethodException();
330 | }
331 | }
332 |
333 | /**
334 | * 给定方法名和参数,匹配一个最接近的方法
335 | */
336 | private Method similarMethod(String name, Class>[] types)
337 | throws NoSuchMethodException {
338 | Class> type = type();
339 |
340 | // 对于公有方法:
341 | for (Method method : type.getMethods()) {
342 | if (isSimilarSignature(method, name, types)) {
343 | return method;
344 | }
345 | }
346 |
347 | // 对于私有方法:
348 | do {
349 | for (Method method : type.getDeclaredMethods()) {
350 | if (isSimilarSignature(method, name, types)) {
351 | return method;
352 | }
353 | }
354 |
355 | type = type.getSuperclass();
356 | } while (type != null);
357 |
358 | throw new NoSuchMethodException("No similar method " + name
359 | + " with params " + Arrays.toString(types)
360 | + " could be found on type " + type() + ".");
361 | }
362 |
363 | /**
364 | * 再次确认方法签名与实际是否匹配, 将基本类型转换成对应的对象类型, 如int转换成Int
365 | */
366 | private boolean isSimilarSignature(Method possiblyMatchingMethod,
367 | String desiredMethodName, Class>[] desiredParamTypes) {
368 | return possiblyMatchingMethod.getName().equals(desiredMethodName)
369 | && match(possiblyMatchingMethod.getParameterTypes(),
370 | desiredParamTypes);
371 | }
372 |
373 | /**
374 | * 调用一个无参构造器
375 | *
376 | * 等价于 create(new Object[0])
377 | *
378 | * @return 工具类自身
379 | * @throws ReflectException
380 | * @see #create(Object...)
381 | */
382 | public Reflect create() throws ReflectException {
383 | return create(new Object[0]);
384 | }
385 |
386 | /**
387 | * 调用一个有参构造器
388 | *
389 | * @param args
390 | * 构造器参数
391 | * @return 工具类自身
392 | * @throws ReflectException
393 | */
394 | public Reflect create(Object... args) throws ReflectException {
395 | Class>[] types = types(args);
396 |
397 | try {
398 | Constructor> constructor = type().getDeclaredConstructor(types);
399 | return on(constructor, args);
400 | }
401 |
402 | // 这种情况下,构造器往往是私有的,多用于工厂方法,刻意的隐藏了构造器。
403 | catch (NoSuchMethodException e) {
404 | // private阻止不了反射的脚步:)
405 | for (Constructor> constructor : type().getDeclaredConstructors()) {
406 | if (match(constructor.getParameterTypes(), types)) {
407 | return on(constructor, args);
408 | }
409 | }
410 |
411 | throw new ReflectException(e);
412 | }
413 | }
414 |
415 | /**
416 | * 为包装的对象创建一个代理。
417 | *
418 | * @param proxyType
419 | * 代理类型
420 | * @return 包装对象的代理者。
421 | */
422 | @SuppressWarnings("unchecked")
423 | public P as(Class
proxyType) {
424 | final boolean isMap = (object instanceof Map);
425 | final InvocationHandler handler = new InvocationHandler() {
426 | @SuppressWarnings("null")
427 | @Override
428 | public Object invoke(Object proxy, Method method, Object[] args)
429 | throws Throwable {
430 | String name = method.getName();
431 |
432 | try {
433 | return on(object).call(name, args).get();
434 | } catch (ReflectException e) {
435 | if (isMap) {
436 | Map