1:所写的东西都经过验证,保证正确,环境jdk8,eclipse
2:在例子中,尽量以生产环境中实际代码为例,那种固定值什么的没什么意义
DynamicQuartzJob Logger logger = LoggerFactory.getLogger(DynamicQuartzJob. executeInternal(JobExecutionContext jobexecutioncontext)
JobDetailImpl jobDetail == JobExecutionException("can not find service info, because desription is empty"= name.split("\\."
String beanName = serviceInfo[1
String methodName = serviceInfo[2==
JobDataMap dataMap ==== JSONObject.toBean(JSONObject.fromObject(dataMap.get("data"
"%s %d" .aa = .bb = main(String[] args)
String str = "{\r\n" + " \"aa\": \"zhangsan\",\r\n" + " \"bb\": 1\r\n" + "}"
Test test = Test(); test = (Test) JSONObject.toBean(JSONObject.fromObject(str), Test.
5:拓展
(1):这张图片是常用的反射方法
(2 java.lang.reflect.* main(String[] args)
HelloKitty ht = =
Class clazz1 = HelloKitty.
Class clazz2 = Class.forName("HelloKitty"
ClassLoader c == String.
Object obj =
Constructor[] con =+ " "
Method[] mm =+ " "
Method m = clazz2.getMethod("walk",=+ " "
Method m1 = clazz2.getMethod("walk", "hahahhha"
Constructor cc = clazz2.getConstructor(.,String.= cc.newInstance(12,"blue"
Field ffs = clazz2.getDeclaredField("age"29= String color = "pink" HelloKitty(.age = HelloKitty(.age =.color ="okokok" "hhhhhhhhhhhhh" talk(+ "----------" +
6:如果只是应用,网上文章一大堆,用就要知道一些具体的细节,不然 emmmm.....(不引战,懂就好)
这里说一下核心方法 method.invoke
(1)这是invoke 的入口方法/**
* Invokes the underlying method represented by this {@code Method}
* object, on the specified object with the specified parameters.
* Individual parameters are automatically unwrapped to match
* primitive formal parameters, and both primitive and reference
* parameters are subject to method invocation conversions as
* necessary.
*
*If the underlying method is static, then the specified {@code obj}
* argument is ignored. It may be null.
*
*If the number of formal parameters required by the underlying method is
* 0, the supplied {@code args} array may be of length 0 or null.
*
*If the underlying method is an instance method, it is invoked
* using dynamic method lookup as documented in The Java Language
* Specification, Second Edition, section 15.12.4.4; in particular,
* overriding based on the runtime type of the target object will occur.
*
*If the underlying method is static, the class that declared
* the method is initialized if it has not already been initialized.
*
*If the method completes normally, the value it returns is
* returned to the caller of invoke; if the value has a primitive
* type, it is first appropriately wrapped in an object. However,
* if the value has the type of an array of a primitive type, the
* elements of the array are not wrapped in objects; in
* other words, an array of primitive type is returned. If the
* underlying method return type is void, the invocation returns
* null.
*
* @param obj the object the underlying method is invoked from
* @param args the arguments used for the method call
* @return the result of dispatching the method represented by
* this object on {@code obj} with parameters
* {@code args}
*
* @exception IllegalAccessException if this {@code Method} object
* is enforcing Java language access control and the underlying
* method is inaccessible.
* @exception IllegalArgumentException if the method is an
* instance method and the specified object argument
* is not an instance of the class or interface
* declaring the underlying method (or of a subclass
* or implementor thereof); if the number of actual
* and formal parameters differ; if an unwrapping
* conversion for primitive arguments fails; or if,
* after possible unwrapping, a parameter value
* cannot be converted to the corresponding formal
* parameter type by a method invocation conversion.
* @exception InvocationTargetException if the underlying method
* throws an exception.
* @exception NullPointerException if the specified object is null
* and the method is an instance method.
* @exception ExceptionInInitializerError if the initialization
* provoked by this method fails. */@CallerSensitive public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException
{ if (!override) { if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
MethodAccessor ma = methodAccessor; // read volatile
if (ma == null) {
ma = acquireMethodAccessor();
} return ma.invoke(obj, args);
}
(2)这段英文就不具体翻译啦,大致意思就是使用这个方法的各种可能情况,可能出现的问题,特别提醒,如果练习英语但是不会FQ,看不到国外的文章可以看底层代码的注释,一样可以练习英语
(3)开始正式解读这个方法,首先说一下这注解@CallerSensitive
2->反射1->
(3):invoke方法可以分为俩部分,一部分是访问控制检查,第一个if;第二部分就是MethodAccessor。invoke()实现执行方法
针对第一部分:简单来说就是访问权限检查,判断你是否可以访问这个方法
具体来说就是: 检查override,如果override为true,(Method的父类AccessibleObject中声明的变量)跳过检查;否则继续; 快速检查,判断该方法的修饰符modifiers是否为public,如果是跳过检查;否则继续; 详细检查,通过方法的( protected / private / package )修饰符或方法的声明类(例如子类可以访问父类的protected方法)与调用者caller之间的关系,判断caller是否有权限访问该方法。这里推荐看一下java四种访问权限,可能我们一般只用到private和public,但访问权限控制很重要,在一些多人合作的项目中尤为重要
这里就涉及到一个有意思的 Field(他父类也是AccessibleObject),他的override是false,导致我们在获取属性是常用setAccessible(true),当属性为private修饰
针对第二部分MethodAccessor.invoke();也就是真正的调用方法
这里有一个注释 // read volatile,这个很有意思是,volatile 是一个类型修饰符。volatile 的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略。//这是methodAccessor,对应的代码private volatile MethodAccessor methodAccessor;
MethodAccessor tmp = (root != ) tmp = (tmp != =
tmp = reflectionFactory.newMethodAccessor(
=
(root != //这个方法可能会导致类膨胀
//类膨胀:类的膨胀(Bloating)指的是类中成员过多,甚至出现无序增加的情况。过大的类,会使得复杂度急剧增加,维护会变得更为困难。所以需要控制类的增长。
//,这篇文章讲解类膨胀= = =
注意这个方法acquireMethodAccessor,他有一个调用反射工厂的过程,ReflectionFactory利用MethodAccessor的字节码生成类MethodAccessorGenerator直接创建一个代理类,通过间接调用原方法完成invoke()任务;
这句话有几个概念:字节码,动态代理,反射最终都是调用原始类
这些遗留问题日后在解决把!!!
7:总结一下我理解的反射和应用场景
(1)反射的概念:可以理解成你去了一个小黑屋,里面可能有各种东西,都上了锁,你通过反射就能获取里面的东西,并且去除锁,知道东西的真正面目
(2)反射应用场景:简单来说就是“动态带有固定”,举个例子,比如我上面的例子,方法是动态的,但是方法的参数是固定的;传入的参数固定的,但是顺序未必和方法一致的;
有话说:看完觉得有用的话可以点赞+评论,今后会分享更多关于java知识相关的文章!