正直なところ、7年間働いている年配の女性プログラマーとして、私はソースコードを見たことがありません。未来の混乱によって強制されます。現状を変えたい。これまでの仕事とは違うことをしたいです。
ソースコードの出発点を見て、大神のコードがどのように書かれているかを知りたいし、他の人の考えを知りたいです。次に、それが自分自身であるかどうかを考えます。
トレーニングスクールの教師は、csdnは開発者がコミュニケーションをとるのに最適なWebサイトであると語っています。ここに、私の啓蒙と学習のウェブサイトがあります。旗を立てました。使用しているソースコードを更新したい。アップデートが完了する前にキャリアを変えるかもしれませんが、何かしたいだけです。
誰にも証明しないでください。うまく始めて終わりたいだけです。過去のアカウントを持っています。何かをエクスポートして決済できることがわかりました。
1つ:以下はmybatisパッケージのディレクトリです。今日の主人公はリフレクションパッケージです。
2:このリフレクションパッケージ、私は見下ろします、最も重要なのは次のカテゴリです、私は主要な方法をリストしました。リフレクターリフレクターは、反射を処理する最下層です。この図の方法は、最も完全なものではありません。キー列のみを選択します。
上の図からわかります。MetaObjectの制御は、基本的にObjectWrapperに渡されて制御されます。ObjectWrapperのクラスの制御は、MetaClassクラスに依存し、MetaClassクラスはReflectorFactoryとReflectorに依存します。
上記は最も単純な属性です。属性が次のような場合、単語のセグメンテーションが実行され、上記のgetValueとsetValueが再帰ループに入ります。自分でテストできます。
@Test
void shouldGetAndSetNestedProperty() {
RichType rich = new RichType();
MetaObject meta = SystemMetaObject.forObject(rich);
meta.setValue("richType.richProperty", "foo");
assertEquals("foo", meta.getValue("richType.richProperty"));
}
三: MetaObject 对象的 setValue 和 getValue 里面用了递归,递归的控制是由分词器PropertyTokenizer 来控制结束的。里面有单测类,强烈建议运行下单测看数据。就能理解我为啥说setValue 难。为啥麻烦。
トークナイザーPropertyTokenizerは、リフレクションパケットに現れる可能性が特に高くなります。
4:PropertyTokenizer分析は、次の図に示すとおりです。
5:今日は分析の最初の日です。初めて読んだのですが、7、8レベルは理解できるかもしれませんが、表現が鮮やかではないかもしれません。うまく書けないなら許してください。以下では、単一のテストと段階的な注釈付きソースコードを使用しています
恥ずかしいことに、この記事ではコードパッケージは許可されていません。コードをリソースファイルに入れました。ポイントなしでリソースファイルをダウンロードできます。https://download.csdn.net/download/lileronglilerong/15120273
6:追加のサプリメント
a:上記のコードを見ると、理解できない文章に遭遇しました。自分で理解してください。機能について
package com.llr.reflect.test;
import java.util.function.Function;
public class FunctionTest {
public static void main(String[] args) {
String s="1234";
/* method(s,(String inputValue)->{
return Integer.parseInt(inputValue);
});*/
// 这个写法和上面的是一样的
method(s, Integer::parseInt);
/**
* Reflector::new 等价于下面的表达式
* Function<Class,Reflector> function=input->new Reflector(input);
*/
}
public static void method(String s, Function<String,Integer> function){
Integer i=function.apply(s);
System.out.println(i);
}
}
b:computeIfAbsent和isAssignableFrom
package com.llr.reflect.test;
import java.util.HashMap;
public class MapTest {
public static void main(String[] args) {
/**
* 1: computeIfAbsent的方法
* computeIfAbsent的方法有两个参数 第一个是所选map的key,第二个是需要做的操作。这个方法当key值不存在时才起作用
*/
HashMap map=new HashMap();
// java8之前。从map中根据key获取value操作可能会有下面的操作
Object value = map.get("key");
if (value == null) {
value = new Object();
map.put("key", value);
}
// java8之后。上面的操作可以简化为一行,若key对应的value为空,会将第二个参数的返回值存入并返回
Object key2 = map.computeIfAbsent("key", k -> new Object());
/**
* 2:isAssignableFrom (is Assignable(可分配)) instanceof
*
* ClassA.isAssignableFrom(ClassB); 表示ClassA是ClassB父类就返回true,否则返回false
*
* 父类.class.isAssignableFrom(子类.class)
* 子类实例 instanceof 父类类型
*/
}
}
c:例は何ですか?
package com.llr.reflect.test;
public class BaseTest {
public static void main(String[] args) {
/**
* 1: 什么是java的实例,什么是引用,什么是引用地址,什么是内存地址。
*
* Cat c 的意思是,在内存中分配一个变量,名字叫c,这个变量是Cat类型的
*
* new Cat(); 说明 new这个Cat类的一个对象,程序运行的时候,会调用构造方法Cat(),等这个构造方法执行完了,这个Cat类型的对象也就造出来了,真正的出现在内存当中了
*
* c就是引用,不是对象!我们new出来的这个东西,真正在内存中的这个东西叫做对象,叫做实例.
*/
Cat c = new Cat();
/**
*
* 2: 单例模式 和 静态方法。
*
* 这个怎么区分,如何进行使用。
*
* 目标:
* a: 弄明白什么是单例模式,什么是 静态方法。
* b: 弄明白二者的区别。
* c: 弄明白适合的场景
*
* 静态方法和非静态方法:
* 一: 静态方法和非静态方法。他们都是在第一次加载后就常驻内存
* 二:
* 在内存中的区别,非静态方法,创建实例对象的时候,因为属性的值对于每个对象不同,故new一个实例的时候,会把
* 实例属性在GC heap 里copy一份,同时这个new出来的对象放在堆栈上,堆栈指针指向了刚才拷贝的那一份实例的内存地址上。
* 而静态方法不需要。因为静态方法里面的静态字段,就是保存再 method table 里的,就只有一份。
*
* 三: 早期几乎所有方法都是“静态方法”,引入实例化方法概念是面向对象概念出险以后的事情。
*
* 结论:静态方法和实例方法是为了解决模式问题。 如果一个方法和他所在类的实例对象无关,那么他应该是静态的。否则应该是非静态的,像工具类,一般都是静态的
*
* 为什么使用单例模式而不用静态方法?
* 如果一个方法和他所在类的实例对象无关,那么他应该是静态的,反之他就应该是非静态的,如果我们确实应该使用非静态的
* 方法,但是在创建类时又确实只需要维护一份实例时,就需要用单例模式。
*
*/
}
static class Cat{
public Cat() {
}
}
}
d:
Classクラスにはいくつかのメソッドがあり、Methodクラスにはいくつかのメソッドがあります。ParamNameUtilメソッドを見ると、最初に発見しました
Executable 类是 :方法和Constructor的共同功能的共享超类
package com.llr.reflect.test;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;
public class MethodTest {
public static void main(String[] args) {
try {
/**
* 1: Class 类中的 区别是什么:getMethod,getDeclaredMethod
*/
Class studentClass = Student.class;
// Member 接口中的 PUBLIC和 DECLARED就有对应的描述
// getMethod 返回所有公用的(public) 包括继承的, 如果 getName 给的是private的话,是会报错的。
Method getNameMethod = studentClass.getMethod("getName");
// getDeclaredMethod 返回包括公用的,私有的,默认的,但是不包括继承的
Method setNameMethod = studentClass.getDeclaredMethod("setName", String.class);
System.out.println(getNameMethod.getName());
System.out.println(setNameMethod.getName());
/**
*
* 2: getDeclaringClass 和 getClass区别
* getDeclaringClass
* 返回的是 (返回 类表示声明该对象表示的可执行的类或接口对象。 )
* class com.llr.reflect.test.MethodTest$Student
*
* getClass: (返回此Object的运行时类。 返回的类对象是被表示类的static synchronized方法锁定的对象。 )
* 返回的是:class java.lang.reflect.Method
*/
System.out.println("+++++++++++++++++");
System.out.println(getNameMethod.getDeclaringClass());
System.out.println(getNameMethod.getClass());
/**
* 3: getParameterTypes和getGenericParameterTypes区别
*
* getParameterTypes 无法取到对象中是泛型的结构化参数。 setAgeList:List
* getGenericParameterTypes 可以取到对象中泛型的结构化参数。 setAgeList:java.util.List<java.lang.Integer>
*
*/
System.out.println("+++++++++++++++++");
Method[] methods = studentClass.getMethods();
Arrays.stream(methods).forEach(method -> {
Class[] pType = method.getParameterTypes();
Type[] gPType = method.getGenericParameterTypes();
if (method.getName().contains("setAgeList")) {
for (Class aClass : pType) {
System.out.println(method.getName() + ":" + aClass.getSimpleName());
}
for (Type type : gPType) {
System.out.println(method.getName() + ":" + type.getTypeName());
}
}
});
System.out.println("+++++++++++++++++");
/**
* 2: Method 中的getGenericReturnType和getType的区别,
*
* Class 实现了 Type 接口。Type 是更上层的接口
*
* getType 输出 class java.lang.Object,而 getGenericType 输出的是 T。
*
* 如果 getGenericSignature 不为空,即如果当前类型是泛型,则返回泛型类型,反之返回 getType() 的值
*/
Class getAge = ReturnTypeTest.class.getDeclaredFields()[0].getType();
Type getGenericAge = ReturnTypeTest.class.getDeclaredFields()[0].getGenericType();
System.out.println(getAge.getSimpleName());
System.out.println(getGenericAge.getTypeName());
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
static class Student {
private String name;
private List<Integer> ageList;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Integer> getAgeList() {
return ageList;
}
public void setAgeList(List<Integer> ageList) {
this.ageList = ageList;
}
}
static class ReturnTypeTest<T> {
T ageInfo;
}
}