当前位置: 首页 > news >正文

第十章 反射

反射机制 

1. 反射机制是JDK中的类库,这套类库可以帮助 操作/读取 class字节码文件。

2. 后期学习的大量JAVA框架,底层是基于反射机制实现的

3. 反射机制可以让程序更加灵活,怎么灵活???

4. 反射机制最核心的几个类:        

        java.lang.Class: Class类型的实例代表硬盘上的某个class文件,或者说代表某一种类型

        String.class文件  String类型

        System.class文件  System类型

        Date.class文件    Date类型

java.lang.reflect.Filed:Filed类型的实例代表类中的属性/字段

java.lang.reflect.Constructor: Constructor类型的实例代表类中的构造方法

java.lang.reflect.Method: Method类型的实例代表类中的方法

获取Class的三种方式:

        第一种方式:Class c = Class.forName("完整的全限定类名");

                注意:

                1.全限定类名是带有包名的。

                2.是lang包下的,java.lang也不能省略。

                3.这是个字符串参数。

                4.如果这个类根本不存在,运行时会报异常:java.lang.ClassNotFoundException

                5.这个方法的执行会导致类的加载动作的发生。

        第二种方式:Class c = obj.getClass();

                注意:这个方法是通过引用去调用的。

        第三种方式:在java语言中,任何一种类型,包括基本数据类型,都有 .class 属性。用这个属性可以获取Class实例。

public class User {// 静态代码块;执行顺序 早于非静态代码块和构造方法static {System.out.println("User类的静态代码块执行了!");}private String name;private int age;public User(String name, int age) {this.name = name;this.age = age;}public User() {System.out.println("User类的无参数构造方法执行了!");}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
public class ReflectTest01 {public static void main(String[] args) throws ClassNotFoundException {// stringClass 就代表 String类型。// stringClass 就代表硬盘上的 String.class文件。      下面这行的代码指的是类加载的过程// stringClass中的class是在堆里面的Class stringClass = Class.forName("java.lang.String");System.out.println("stringClass:" + stringClass);   // stringClass:class java.lang.String// 获取 User 类型Class userClass = Class.forName("com.powernode.javase.reflect.User");System.out.println("userClass:" + userClass);   // userClass:class com.powernode.javase.reflect.UserString s1 = "动力节点";Class stringClass2 = s1.getClass();// 某种类型的字节码文件在内存当中只有一份。// stringClass 和 stringClass2 都代表了同一种类型:String类型System.out.println(stringClass == stringClass2);        // trueUser user = new User("zhangsan", 20);Class userClass2 = user.getClass();System.out.println(userClass2 == userClass); // true// intClass 代表的就是基本数据类型 int类型Class intClass = int.class;Class doubleClass = double.class;Class stringClass3 = String.class;Class userClass3 = User.class;System.out.println(userClass3);     // class com.powernode.javase.reflect.UserSystem.out.println(doubleClass);    // doubleSystem.out.println(stringClass3 == stringClass); // true}
}

获取Class的第四种方式

类加载器

首先是字节码文件,字节码文件传入到类的加载过程中,首先是装载(loading),然后是链接(Linking),最后是初始化(Initialization)

类加载的过程

public class ReflectTest14 {public static void main(String[] args) throws Exception {// 获取类加载器对象(获取的是 系统类加载器/应用类加载器 )ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();     // 获取Class的第四种方式// jdk.internal.loader.ClassLoaders$AppClassLoader@36baf30c// 这个类加载器是负责加载 classpath 中的字节码文件的。// System.out.println(systemClassLoader);// 加载类:但是这个加载过程只是将类加载过程中的前两步完成了,第三步的初始化没做。// 什么时候做初始化?在这个类真正的被第一次使用的时候。Class<?> aClass = systemClassLoader.loadClass("com.powernode.javase.reflect.User");     // 获取Class的第四种方式System.out.println(aClass.newInstance());// 这种方式会走完类加载的全部过程,三步齐全//Class clazz = Class.forName("com.powernode.javase.reflect.User");}
}

三种不同的类加载器

 双亲委派机制

/*** 虚拟机内部有三个不同的类加载器:*      1. 启动类加载器:BootstrapClassLoader*          负责加载核心类库*      2. 平台类加载器:PlatformClassLoader*          负责加载扩展类库*      3. 应用类加载器:AppClassLoader*          负责加载classpath** 类加载器也是可以自定义的,只要符合类加载器的规范即可。* 自定义的类加载器,我们一般称为:用户类加载器。*/
public class ReflectTest15 {public static void main(String[] args) {// 通过自定义的类获取的类加载器是:应用类加载器。ClassLoader appClassLoader = ReflectTest15.class.getClassLoader();System.out.println("应用类加载器:" + appClassLoader);// 获取应用类加载器ClassLoader appClassLoader2 = ClassLoader.getSystemClassLoader();System.out.println("应用类加载器:" + appClassLoader2);// 获取应用类加载器ClassLoader appClassLoader3 = Thread.currentThread().getContextClassLoader();System.out.println("应用类加载器:" + appClassLoader3);// 通过 getParent() 方法可以获取当前类加载器的 “父 类加载器”。// 获取平台类加载器。System.out.println("平台类加载器:" + appClassLoader.getParent());// 获取启动类加载器。// 注意:启动类加载器负责加载的是JDK核心类库,这个类加载器的名字看不到,直接输出的时候,结果是null。System.out.println("启动类加载器:" + appClassLoader.getParent().getParent());}
}

获取到class之后

实例化对象

public class ReflectTest02 {public static void main(String[] args) throws Exception{// 获取到Class类型的实例之后,可以实例化对象// 通过反射机制实例化对象Class userClass = Class.forName("com.powernode.javase.reflect.User"); // userClass 代表的就是 User类型。// 通过userClass来实例化User类型的对象// 底层实现原理是:调用了User类的无参数构造方法完成了对象的实例化。// 要使用这个方法实例化对象的话,必须保证这个类中是存在无参数构造方法的。如果没有无参数构造方法,则出现异常:java.lang.InstantiationExceptionUser user = (User)userClass.newInstance();System.out.println(user);// 每次调用 newInstance() 都会触发类的无参构造方法,生成一个全新的对象实例User user2 = (User)userClass.newInstance();System.out.println(user == user2); // false     底层存储位置不同}
}

读取属性配置文件

1、读取属性配置文件,获取类名,通过反射机制获取实例化对象

2、通过这个案例的演示就知道反射机制是灵活的。这个程序可以做到对象的动态创建

3、只要修改属性配置文件就可以完成不同对象的实例化

className=java.util.Date
public class ReflectTest03 {public static void main(String[] args) throws Exception {// 资源绑定器ResourceBundle bundle = ResourceBundle.getBundle("com.powernode.javase.reflect.classInfo");// 通过key获取valueString className = bundle.getString("className");System.out.println(className);      // java.util.Date// 通过反射机制实例化对象Class classObj = Class.forName(className);System.out.println(classObj);       // class java.util.Date// 实例化Object obj = classObj.newInstance();System.out.println(obj);}
}

类中的字段/属性

关于反射机制中的 java.lang.reflect.Field(代表的是一个类中的字段/属性)

Vip类 

public class Vip {// Fieldpublic String name;private int age;protected String birth;boolean gender;public static String address = "张三";public static final String GRADE = "金牌";
}
public class ReflectTest04 {public static void main(String[] args) throws Exception {// 获取Vip类Class vipClass = Class.forName("com.powernode.javase.reflect.Vip");// 获取Vip类中所有public的属性/字段/*Field[] fields = vipClass.getFields();System.out.println(fields.length);for (Field field : fields) {System.out.println(field.getName());}*/// 获取Vip类中所有的属性/字段        (包括私有的)Field[] fields = vipClass.getDeclaredFields();for (Field field : fields) {// 获取属性名System.out.println(field.getName());// 获取属性类型Class fieldType = field.getType();System.out.println(fieldType);// 获取属性类型的简单名称String simpleName = fieldType.getSimpleName();System.out.println(simpleName);// 获取属性的修饰符
//            System.out.println(field.getModifiers());System.out.println(Modifier.toString(field.getModifiers()));System.out.println("************************************");}}
}

获取类型名

public class ReflectTest05 {public static void main(String[] args) {// c 代表 String 类型Class c = "动力节点".getClass();// 获取类型名System.out.println(c.getName());    // java.lang.String// 获取不带包名的简短类名System.out.println(c.getSimpleName());  // String}
}

获取指定Vip类中的所有属性

public class ReflectTest06 {public static void main(String[] args) throws Exception{// 获取String类Class stringClass = Class.forName("com.powernode.javase.reflect.Vip");System.out.println(stringClass.getModifiers());     // 1// 字符串拼接StringBuilder sb = new StringBuilder();// 获取类的修饰符sb.append(Modifier.toString(stringClass.getModifiers()));   // publicsb.append(" class ");//sb.append(stringClass.getSimpleName());sb.append(stringClass.getName());sb.append(" extends ");// 获取当前类的父类sb.append(stringClass.getSuperclass().getName());// 获取当前类的实现的所有接口Class[] interfaces = stringClass.getInterfaces();if(interfaces.length > 0){System.out.println();sb.append(" implements ");for (int i = 0; i < interfaces.length; i++) {Class interfaceClass = interfaces[i];sb.append(interfaceClass.getName());if(i != interfaces.length - 1){sb.append(",");}}}sb.append("{\n");// 获取所有属性Field[] fields = stringClass.getDeclaredFields();for (Field field : fields){sb.append("\t");sb.append(Modifier.toString(field.getModifiers()));     // 修饰符sb.append(" ");sb.append(field.getType().getSimpleName());       // 类型sb.append(" ");sb.append(field.getName());         // 属性名sb.append(";\n");}sb.append("}");// 输出System.out.println(sb);}
}

通过反射机制访问Field,给属性赋值,读取属性的值 

public class Customer {public String name;private int age;
}
public class ReflectTest07 {public static void main(String[] args) throws Exception {// 如果不使用反射机制,怎么访问对象的属性?Customer customer = new Customer();// 修改属性的值(set动作)// customer要素一// name要素二// "张三"要素三customer.name = "张三";// 读取属性的值(get动作)// 读取哪个对象的哪个属性System.out.println(customer.name);// 如果使用反射机制,怎么访问对象的属性?// 获取类Class clazz = Class.forName("com.powernode.javase.reflect.Customer");// 获取对应的Field(属性)Field ageField = clazz.getDeclaredField("age");//        Field nameField = clazz.getDeclaredField("name");//        Field[] fields = clazz.getDeclaredFields();// 调用方法打破封装ageField.setAccessible(true);// 修改属性的值// 给对象属性赋值三要素:给哪个对象 的 哪个属性 赋什么值ageField.set(customer, 30);// 读取属性的值System.out.println("年龄:" + ageField.get(customer));// 通过反射机制给name属性赋值,和读取name属性的值Field nameField = clazz.getDeclaredField("name");// 修改属性name的值nameField.set(customer, "李四");// 读取属性name的值System.out.println(nameField.get(customer));}
}

方法名及参数类型

UserService

public class UserService {/*public void login(){}*//*** 登录系统的方法* @param username 用户名* @param password 密码* @return true表示登录成功,false表示失败*/public boolean login(String username, String password){/*if("admin".equals(username) && "123456".equals(password)){return true;}return false;*/return "admin".equals(username) && "123456".equals(password);}public String concat(String s1, String s2, String s3){return s1 + s2 + s3;}/*** 退出系统的方法*/public void logout(){System.out.println("系统已安全退出!");}
}

反射一个类中的所有方法及参数类型 

public class ReflectTest08 {public static void main(String[] args) throws Exception {// 获取类Class clazz = Class.forName("com.powernode.javase.reflect.UserService");// 获取所有的方法,包含私有的方法Method[] methods = clazz.getDeclaredMethods();//System.out.println(methods.length);// 遍历数组for(Method method : methods){// 方法修饰符System.out.println(Modifier.toString(method.getModifiers()));// 方法返回值类型System.out.println(method.getReturnType().getName());// 方法名System.out.println(method.getName());// 方法的参数列表/*Class<?>[] parameterTypes = method.getParameterTypes();for (Class parameterType : parameterTypes){System.out.println(parameterType.getName());}*/Parameter[] parameters = method.getParameters();for (Parameter parameter : parameters){System.out.println(parameter.getType().getName());System.out.println(parameter.getName());// arg0, arg1, arg2......}System.out.println("*************************");}}
}

反射一个类中所有的方法,然后进行拼接字符串

public class ReflectTest09 {public static void main(String[] args) throws Exception{StringBuilder sb = new StringBuilder();Class stringClass = Class.forName("com.powernode.javase.reflect.UserService");// 获取类的修饰符sb.append(Modifier.toString(stringClass.getModifiers()));sb.append(" class ");// 获取类名sb.append(stringClass.getName());// 获取父类名sb.append(" extends ");sb.append(stringClass.getSuperclass().getName());// 获取父接口名Class[] interfaces = stringClass.getInterfaces();if(interfaces.length > 0){sb.append(" implements ");for (int i = 0; i < interfaces.length; i++) {sb.append(interfaces[i].getName());if(i != interfaces.length - 1){sb.append(",");}}}sb.append("{\n");// 类体// 获取所有的方法Method[] methods = stringClass.getDeclaredMethods();for(Method method : methods){sb.append("\t");// 追加修饰符sb.append(Modifier.toString(method.getModifiers()));// 追加返回值类型sb.append(" ");sb.append(method.getReturnType().getName());// 追加方法名sb.append(" ");sb.append(method.getName());sb.append("(");// 追加参数列表Parameter[] parameters = method.getParameters();for (int i = 0; i < parameters.length; i++) {Parameter parameter = parameters[i];sb.append(parameter.getType().getName());sb.append(" ");sb.append(parameter.getName());if(i != parameters.length - 1){sb.append(", ");}}sb.append("){}\n");}sb.append("}");// 输出System.out.println(sb);}
}

反射机制调用Method

public class ReflectTest10 {public static void main(String[] args) throws Exception {// 不使用反射机制怎么调用方法?// 创建对象UserService userService = new UserService();// 调用方法// 分析:调用一个方法需要几个要素?四要素// 调用哪个对象的哪个方法,传什么参数,返回什么值boolean isSuccess = userService.login("admin", "123456");System.out.println(isSuccess ? "登录成功" : "登录失败");// 调用方法userService.logout();// 通过反射机制调用login方法// 获取ClassClass clazz = Class.forName("com.powernode.javase.reflect.UserService");// 获取login方法    第一个传入参数是方法名String类型Method loginMethod = clazz.getDeclaredMethod("login", String.class, String.class);// 调用login方法Object retValue = loginMethod.invoke(userService, "admin", "123456");System.out.println(retValue);// 调用logout方法Method logoutMethod = clazz.getDeclaredMethod("logout");logoutMethod.invoke(userService);}
}

反射机制获取类中的所有构造方法

public class Order {private String no;private double price;private String state;@Overridepublic String toString() {return "Order{" +"no='" + no + '\'' +", price=" + price +", state='" + state + '\'' +'}';}public Order() {}public Order(String no) {this.no = no;}public Order(String no, double price) {this.no = no;this.price = price;}public Order(String no, double price, String state) {this.no = no;this.price = price;this.state = state;}public String getNo() {return no;}public void setNo(String no) {this.no = no;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}public String getState() {return state;}public void setState(String state) {this.state = state;}}
public class ReflectTest11 {public static void main(String[] args) throws Exception {StringBuilder sb = new StringBuilder();// 获取类Class clazz = Class.forName("com.powernode.javase.reflect.Order");// 类的修饰符sb.append(Modifier.toString(clazz.getModifiers()));sb.append(" class ");// 类名sb.append(clazz.getName());sb.append(" extends ");// 父类名sb.append(clazz.getSuperclass().getName());// 实现的接口Class[] interfaces = clazz.getInterfaces();if(interfaces.length > 0) {sb.append(" implements ");for (int i = 0; i < interfaces.length; i++) {sb.append(interfaces[i].getName());if(i != interfaces.length - 1){sb.append(",");}}}sb.append("{\n");//类体// 获取所有的构造方法Constructor[] cons = clazz.getDeclaredConstructors();// 遍历所有的构造方法for(Constructor con : cons){sb.append("\t");// 构造方法修饰符sb.append(Modifier.toString(con.getModifiers()));           // 重要的获取方法修饰符sb.append(" ");// 构造方法名sb.append(con.getName());sb.append("(");// 构造方法参数列表Parameter[] parameters = con.getParameters();for (int i = 0; i < parameters.length; i++) {Parameter parameter = parameters[i];sb.append(parameter.getType().getName());sb.append(" ");sb.append(parameter.getName());if(i != parameters.length - 1){sb.append(",");}}sb.append("){}\n");}sb.append("}");System.out.println(sb);}
}

反射机制调用构造方法创建对象

public class ReflectTest12 {public static void main(String[] args) throws Exception {// 不使用反射机制的时候,怎么创建的对象?Order order1 = new Order();System.out.println(order1);        // Order{no='null', price=0.0, state='null'}Order order2 = new Order("1111122222", 3650.5, "已完成");System.out.println(order2);// 通过反射机制来实例化对象?Class clazz = Class.forName("com.powernode.javase.reflect.Order");// 这种方式依赖的是必须有一个无参数构造方法。如果没有会出现异常!// 在Java9的时候,这个方法被标注了已过时。不建议使用了。/*Object obj = clazz.newInstance();System.out.println(obj);*/// 获取Order的无参数构造方法Constructor defaultCon = clazz.getDeclaredConstructor();// 调用无参数构造方法实例化对象Object obj = defaultCon.newInstance();System.out.println(obj);        // Order{no='null', price=0.0, state='null'}// 获取三个参数的构造方法Constructor threeArgsCon = clazz.getDeclaredConstructor(String.class, double.class, String.class);// 调用三个参数的构造方法Object obj1 = threeArgsCon.newInstance("5552454222", 6985.0, "未完成");System.out.println(obj1);}
}

模仿框架

通过读取属性配置文件,获取类信息,方法信息,然后通过反射机制调用方法

className=com.powernode.javase.reflect.UserService
methodName=concat
parameterTypes=java.lang.String,java.lang.String,java.lang.String
parameterValues=abc,def,xyz
public class ReflectTest13 {public static void main(String[] args) throws Exception {// 读取属性配置文件ResourceBundle bundle = ResourceBundle.getBundle("com.powernode.javase.reflect.config");String className = bundle.getString("className");   // 目标类的全限定名(如 java.lang.String)String methodName = bundle.getString("methodName"); // 调用的方法名(如 substring)String parameterTypes = bundle.getString("parameterTypes"); // 方法参数的类型全限定名String parameterValues = bundle.getString("parameterValues");   // 方法参数的具体值System.out.println(className);      // com.powernode.javase.reflect.UserService// 通过反射机制调用方法       类必须存在且可访问// 创建对象(依赖无参数构造方法)Class<?> clazz = Class.forName(className);Constructor<?> defaultCon = clazz.getDeclaredConstructor(); // 获取无参构造方法Object obj = defaultCon.newInstance();  // 实例化对象// 获取方法// java.lang.String,java.lang.StringString[] strParameterTypes = parameterTypes.split(",");// 将配置文件中的参数类型字符串(如 java.lang.String,int)转换为 Class[] 数组Class[] classParameterTypes = new Class[strParameterTypes.length];for (int i = 0; i < strParameterTypes.length; i++) {classParameterTypes[i] = Class.forName(strParameterTypes[i]);System.out.println(classParameterTypes[i]);}// 通过方法名和参数类型数组获取目标 Method 对象       方法名必须是公开的Method method = clazz.getDeclaredMethod(methodName, classParameterTypes);// 调用方法// parameterValues=abc,def,xyz// 将参数值字符串(如 "abc,def,xyz")按逗号分割为数组Object retValue = method.invoke(obj, parameterValues.split(","));System.out.println(retValue);}
}

泛型(反射)

参数化类型是指 ​​带有具体泛型参数的类型​​。 

获取父类的泛型信息

/*** 在类上定义泛型* @param <X>* @param <Y>* @param <Z>*/
public class Animal<X, Y, Z> {}// Cat 类继承 Animal 时,明确指定了父类的泛型参数为 String, Integer, Double
// 泛型参数在编译后会 ​​类型擦除​​,但通过反射可以获取到父类泛型的 ​​实际类型参数
public class Cat extends Animal<String, Integer, Double>{}
public class Test {public static void main(String[] args) {// 获取类Class<Cat> catClass = Cat.class;// 获取当前类的父类泛型Type genericSuperclass = catClass.getGenericSuperclass();System.out.println(genericSuperclass); // com.powernode.javase.reflect.generic01.Animal<java.lang.String, java.lang.Integer, java.lang.Double>// Cat 的父类是 Animal<String, Integer, Double>,属于参数化类型// 若父类未使用泛型(如 Animal),genericSuperclass 会是 Class<Animal>,输出则为 trueSystem.out.println(genericSuperclass instanceof Class);      // falseSystem.out.println(genericSuperclass instanceof ParameterizedType);       // ParameterizedType:参数化类型// 如果父类使用了泛型if(genericSuperclass instanceof ParameterizedType){// 转型为参数化类型ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;// 获取泛型数组Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();// 遍历泛型数组for(Type a : actualTypeArguments){// 获取泛型的具体类型名System.out.println(a.getTypeName());}}}
}

获取接口上的泛型

public interface Flyable<X, Y> {
}// 实现 Comparable<Mouse> → 泛型参数为 Mouse 自身
public class Mouse implements Flyable<String, Integer>, Comparable<Mouse>{@Overridepublic int compareTo(Mouse o) {return 0;}
}
public class Test {public static void main(String[] args) {Class<Mouse> mouseClass = Mouse.class;// 获取接口上的泛型     ParameterizedType 类型Type[] genericInterfaces = mouseClass.getGenericInterfaces();for (Type g : genericInterfaces) {// 使用了泛型if(g instanceof ParameterizedType){// 转型为参数化类型ParameterizedType parameterizedType = (ParameterizedType) g;// 获取泛型数组Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();for(Type a : actualTypeArguments){System.out.println(a.getTypeName());}}}}
}

获取属性上的泛型

public class User {private Map<Integer, String> map;
}
public class Test {public static void main(String[] args) throws Exception{// 获取这个类Class<User> userClass = User.class;// 获取属性上的泛型,需要先获取到属性Field mapField = userClass.getDeclaredField("map"); // 获取公开的以及私有的// 获取这个属性上的泛型Type genericType = mapField.getGenericType();// 用泛型了if(genericType instanceof ParameterizedType){ParameterizedType parameterizedType = (ParameterizedType) genericType;Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();for(Type a : actualTypeArguments){System.out.println(a.getTypeName());}}}
}

获取方法参数上的泛型

public class MyClass {public Map<Integer, Integer> m(List<String> list, List<Integer> list2){return null;}
}
public class Test {public static void main(String[] args) throws Exception{// 获取类Class<MyClass> myClassClass = MyClass.class;// 获取方法Method mMethod = myClassClass.getDeclaredMethod("m", List.class, List.class);// 获取方法参数上的泛型Type[] genericParameterTypes = mMethod.getGenericParameterTypes();for(Type g : genericParameterTypes){// 如果这个参数使用了泛型if(g instanceof ParameterizedType){ParameterizedType parameterizedType = (ParameterizedType) g;Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();for(Type a : actualTypeArguments){System.out.println(a.getTypeName());}}}// 获取方法返回值上的泛型Type genericReturnType = mMethod.getGenericReturnType();if(genericReturnType instanceof ParameterizedType){ParameterizedType parameterizedType = (ParameterizedType) genericReturnType;Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();for(Type a : actualTypeArguments){System.out.println(a.getTypeName());}}}
}

获取构造方法参数的泛型

public class User {public User(Map<String ,Integer> map){}
}
public class Test {public static void main(String[] args) throws Exception{Class<User> userClass = User.class;Constructor<User> con = userClass.getDeclaredConstructor(Map.class);Type[] genericParameterTypes = con.getGenericParameterTypes();for(Type g :genericParameterTypes){if(g instanceof ParameterizedType){ParameterizedType parameterizedType = (ParameterizedType) g;// 泛型数组Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();for(Type a : actualTypeArguments){System.out.println(a.getTypeName());}}}}
}

相关文章:

  • 电动黄油枪行业数据分析报告2025-恒州诚思
  • Python 字典渲染字符串
  • node创建自己的CLI脚手架(强化基础)
  • 苍茫命令行:linux模拟实现,书写微型bash
  • ​​知识图谱:重构认知的智能革命​
  • 【Rust】Rust获取命令行参数以及IO操作
  • ABAQUS三维功能梯度多孔结构材料FGM轴压模拟
  • 第二章 1.6 数据采集安全风险防范之数据源鉴别及记录
  • API 与 SPI
  • ZooKeeper 命令操作
  • 三维点云深度学习代码torch-points3d-SiamKPConvVariants复现记录(持续更新中)
  • Yocto meta-toradex-security layer创建加密数据分区应用说明
  • 高通滤波和低通滤波
  • 针对C语言的开发工具推荐及分析(涵盖编辑器、集成开发环境(IDE)、编译器、调试工具及辅助工具)
  • 电子电路:什么是C类放大器?
  • 【C++基础知识】【ASAN】
  • Kafka KRaft + SSL + SASL/PLAIN 部署文档
  • Python应用while循环猜数字
  • HTML5 视频播放器:从基础到进阶的实现指南
  • 电脑开机后出现bootmgr is conmpressed原因及解决方法
  • 潍坊网站建设SEO优化/seo网站推广优化论文
  • 高职示范校建设专题网站/公关公司是干嘛的
  • 网站架构 seo/seo关键词排名工具
  • 怎么给人介绍自己做的网站/百度提问首页
  • 天津和平做网站哪家好/关键词优化排名软件
  • artisteer 做的网站/查排名官网