反射、注解、动态代理、JDK8新特性

第一章.反射

1.类的加载
源文件--通过javac编译-->字节码文件---通过Java命令(通过ClassLoader)--->JVM运行字节码文件什么时候会被加载?当该类被使用到时就会被加载
字节码文件需要加载几次?       只需要加载一次,当前第一次使用该类时加载,以后使用到该类不需要加载
"字节码文件被加载JVM方法区内存之后,JVM会干什么事?"JVM会在堆中为该字节码文件创建一个Class对象(字节码文件对象),对象中保存了字节码文件中所有的信息

2.什么是反射
反射是一种运行时技术,运行时获取某个类的Class对象,从而解剖它,从中获取成员变量,成员方法,构造方法等,进而可以使用他们(无论私有与否)
3.反射在实际开发中的应用
a.编写IDE(集成开发环境),比如IDEA,Eclipse
b.以后我们底层学习框架和设计框架都必须使用反射技术
4.反射中万物皆对象的概念
反射中万物皆对象:字节码文件 ---> Class对象成员变量 ---> Field对象成员方法 ---> Method对象构造方法 ---> Constructor对象   newInstance ---> 创建对象invoke ---> 调用/执行体验一下反射中语法:正常语法                   反射语法new 构造方法(参数);          构造方法对象.newInstance(参数);对象名.成员方法名(参数);        成员方法对象.invoke(对象名,参数);sout(对象名.成员变量名);   sout(成员变量对象.get(对象名)); 对象名.成员变量名 = 值      成员变量对象.set(对象名,值);

5.反射的第一步获取字节码文件对象(Class对象)
Java提供三种方式,可以获取到Class对象
/*** 获取Class对象*/
public class TestDemo {public static void main(String[] args) throws ClassNotFoundException {//1.通过类的静态成员来获取Class clazz1 = Cat.class;System.out.println(clazz1);//2.通过该类的某个对象,来获取Class对象Cat cc = new Cat();Class clazz2 = cc.getClass();System.out.println(clazz2);//3.通过Class类的静态方法Class clazz3 = Class.forName("com.itheima.demo02_GetClassObject.Cat");System.out.println(clazz3);//注意:以上三种是Java提供的三种方式,而不是获取三个Class对象System.out.println(clazz1 == clazz2);System.out.println(clazz1 == clazz3);System.out.println(clazz2 == clazz3);//以上三个Class对象,实际上是同一个Class对象,只是获取的方式不同而已}
}
6.Class对象中的三个常见方法
public String getName(); 获取全限定类名(包名.类名)
public String getSimpleName(); 获取类名(不带包名)
public Object newInstance();  创建该Class对象所代表类的对象  /*** Class对象的三个方法*/
public class TestDemo {public static void main(String[] args) throws Exception {//1.通过类的静态成员来获取Class clazz1 = Cat.class;//4.获取全限定类名System.out.println("---------------");System.out.println(clazz1.getName());//5.获取类名System.out.println(clazz1.getSimpleName());//6.创建对象(Class所代表类Cat的对象)Object obj = clazz1.newInstance();System.out.println(obj);}
}
7.通过反射获取构造方法&&使用构造方法创建对象
获取构造:public Constructor getConstructor(构造方法的参数类型.class...);只能获取"public"构造public Constructor getDeclaredConstructor(构造方法的参数类型.class...);获取"任意"构造    使用构造:public Object newInstace(构造方法的实际参数);
如果是私有构造怎么使用?a.先设置该构造方法具有暴力访问权限构造方法对象.setAccessible(true);b.然后正常使用public Object newInstace(构造方法的实际参数);/*** 通过反射获取其中的构造方法,并使用构造方法*/
public class TestDemo {public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {//1.获取Class对象Class cc = Cat.class;//2.获取构造方法对象Constructor con1 = cc.getConstructor();System.out.println(con1);Constructor con2 = cc.getConstructor(int.class, String.class);System.out.println(con2);//如果是非公有构造,必须调用getDeclaredConstructor来获取Constructor con3 = cc.getDeclaredConstructor(String.class);System.out.println(con3);//3.通过构造方法对象就可以创建对象System.out.println("---------");Object obj1 = con1.newInstance();System.out.println(obj1);Object obj2 = con2.newInstance(10, "肥猫");System.out.println(obj2);//如果是私有构造方法,那么必须先设置暴力访问权限con3.setAccessible(true);//然后才能正常使用Object obj3 = con3.newInstance("加肥猫");System.out.println(obj3);}
}
8.通过反射获取成员方法&&调用成员方法
获取成员方法:public Method getMethod("方法名",方法参数类型.class...); 获取"public"修饰成员方法public Method getDeclaredMethod("方法名",方法参数类型.class...); 获取"任意"修饰成员方法
使用成员方法:public Object invoke(对象名,执行方法需要的实际参数); -- 执行该成员方法对象
如果是私有的成员方法怎么调用呢?a.先设置暴力访问权限成员方法对象.setAccessible(true);b.正常调用该方法即可public Object invoke(对象名,执行方法需要的实际参数); -- 执行该成员方法对象    /*** 通过反射获取成员变量,并使用成员方法*/
public class TestDemo {public static void main(String[] args) throws Exception {//1.获取Class对象Class cc = Class.forName("com.itheima.demo04_GetMethod.Cat");//2.获取成员方法Method m1 = cc.getMethod("eat", String.class);System.out.println(m1);Method m2 = cc.getMethod("eat", String.class, String.class);System.out.println(m2);//如果成员方法是非公有的,必须通过getDeclaredMethod方法获取Method m3 = cc.getDeclaredMethod("eat");System.out.println(m3);//3.使用成员方法对象Cat cat = new Cat(10,"加菲猫");m1.invoke(cat,"鱼"); // 相当于 cat.eat("鱼")m2.invoke(cat,"鱼","啤酒");// 相当于cat.eat(鱼","啤酒");//如果是私有方法,必须先设置暴力访问权限m3.setAccessible(true);//然后调用正常调用方法m3.invoke(cat); //相当于cat.eat();}
}
9.通过反射获取成员属性(了解即可)
因为成员变量都是私有的,并且有get/set方法,我们通过反射获取get/set方法就可以了!!获取成员变量:public Field getField(String 成员变量名); -- 获取"public"成员变量public Field getDeclaredField(String 成员变量名); -- 获取"任意"成员变量
使用成员变量:  "取出成员变量的值成员变量对象.get(对象名); // 相当于 对象名.成员变量名需要先设置暴力权限成员变量对象.setAccessible(true);成员变量对象.get(对象名);"修改成员变量的值成员变量对象.set(对象名,新的值);需要先设置暴力权限成员变量对象.setAccessible(true);成员变量对象.set(对象名,新的值);
10.反射中的其他方法(了解即可)
获取构造:public Constructor[] getConstructors(); -- 获取所有"public"构造public Constructor[] getDeclaredConstructors(); -- 获取所有"任意"构造
获取方法:public Method[] getMethods(); -- 获取所有"public"成员方法,包括父类继承的public Method[] getDeclaredMethods(); -- 获取所有"任意"成员方法(不包括父类继承的)   获取成员变量:public Filed[] getFields();  -- 获取所有"public"的成员变量       public Filed[] getDeclaredFields();  -- 获取所有"任意"的成员变量  

第二章 注解(基本语法)

1.JDK1.5新特性–注解
什么是注释:对代码进行解释说明的文字(给程序员看)
什么是注解:对代码进行解释说明的语法(给JVM看的,程序员也可以看)
2.注解的两个作用
a.给程序带入参数(框架的时候使用)
b.编译检查(在编译时期,检查我们的语法是否符合程序的要求)@Override 方法重写注解@FunctionalInterface 函数式接口注解@Deprecated 方法过期注解
c.作为框架的配置文件(框架的时候使用)
3.常用两个注解介绍
@author 给Java文件,标记作者
@version 给Java文件,标记版本号
@Override 方法重写注解
@FunctionalInterface 函数式接口注解
@Deprecated 方法过期注解
@Test 单元测试Junit的注解
4.自定义注解
自定义类: public class 类名
自定义接口: public interface 接口名
自定义注解: public @interface 注解名格式:public @interface 注解名{}
5.给自定义注解添加属性
格式:public @interface 注解名{//注解中只能写属性,格式: 数据类型 属性名();数据类型 属性名() [default 默认值]; 数据类型 属性名() [default 默认值];数据类型 属性名() [default 默认值];}
注解中属性的数据类型也是有限制:a.八大基本类型b.引用类型中只能写:String,枚举,其他注解,Classc.以上12种类型的一维数组
6.自定义注解练习
/*** 自定义注解*/
public @interface MyAnnotation {//注解的属性int age(); // default 18;String name();// default "张三";String[] hobbies();// default {"抽烟", "喝酒", "跳楼"};
}/*** 使用注解格式:*  @注解名(属性名=属性值,属性名=属性值,..)*  如果注解中某个属性没有默认值,那么使用该注解时必须给属性赋值,如果有默认值,可以赋值也可以不赋值    */
@MyAnnotation(age = 18,name = "旺财",hobbies = {"抽烟", "喝酒", "跳楼"})
public class Demo {@MyAnnotation(age = 18,name = "旺财",hobbies = {"抽烟", "喝酒", "跳楼"})private String job;@MyAnnotation(age = 18,name = "旺财",hobbies = {"抽烟", "喝酒", "跳楼"})public Demo(String job) {this.job = job;}@MyAnnotation(age = 18,name = "旺财",hobbies = {"抽烟", "喝酒", "跳楼"})public void show(@MyAnnotation(age = 18,name = "旺财",hobbies = {"抽烟", "喝酒", "跳楼"}) int age) {@MyAnnotation(age = 18,name = "旺财",hobbies = {"抽烟", "喝酒", "跳楼"})String name = "";}
}
7.使用注解时的注意事项
a.如果注解中某个属性没有默认值,那么使用该注解时必须给属性赋值,如果有默认值,可以赋值也可以不赋值
b.我们现在定义的注解,可以修饰基本上任意的地方(类上,方法上,局部变量上等...)
c.我们的注解没有实际含义,注解想要有实际含义必须有注解解析器的支持
8.自定义注解中的特殊属性名value
a.如果注解中只有一个属性,且属性名为value,那么使用该注解时,可以省略value直接给value赋值即可
/*** 特殊的属性value*/
public @interface MyAnno {String value();
}
@MyAnno("abc") -- 此处省略value的名,直接写value的值
public class Demo {}
b.如果注解中有多个属性,但是有一个叫value,其他属性都有默认值,使用时可以可以省略value直接给value赋值即可
/*** 特殊的属性value*/
public @interface MyAnno {String value();int age() default 20;
}
@MyAnno("abc") -- 此处省略value的名,直接写value的值,age不需要赋值
public class Demo {}
9.注解的注解–元注解
元注解: 修饰注解的注解,称为元注解
  • 两个元注解

    @Target 元注解,修饰普通的注解其作用是,规定普通的注解使用的目标:具体的使用目标,可以是以下几种ElementType.TYPE  表示作用目标必须是类上或者接口上ElementType.FIELD 表示作用目标必须是成员变量上ElementType.METHOD  表示作用目标必须是成员方法上ElementType.PARAMETER 表示作用目标必须是方法参数上ElementType.CONSTRUCTOR 表示作用目标必须是构造方法上ElementType.LOCAL_VARIABLE  表示作用目标必须是局部变量上
    /*** 使用@Target元注解,修饰普通的注解* 作用:规定普通注解使用的目标*/
    //@Target(ElementType.TYPE) 表示作用目标必须是类上或者接口上
    //@Target(ElementType.FIELD) 表示作用目标必须是成员变量上
    //@Target(ElementType.METHOD) 表示作用目标必须是成员方法上
    //@Target(ElementType.CONSTRUCTOR) 表示作用目标必须是构造方法上
    //@Target(ElementType.PARAMETER) 表示作用目标必须是方法参数上
    //@Target(ElementType.LOCAL_VARIABLE) 表示作用目标必须是局部变量上
    @Target({ElementType.FIELD,ElementType.METHOD}) 表示作用目标必须是成员变量和成员方法上
    public @interface Anno1 {}@Retension 元注解,修饰普通的注解其作用是,规定普通注解的生命周期,具体的使用生命周期,可以是以下几种RetentionPolicy.SOURCE 表示我们的注解只在源码阶段存在,编译成字节码后删除RetentionPolicy.CLASS 表示我们的注解在源码和字节码阶段都存在,运行时删除RetentionPolicy.RUNTIME 表示我们的注解一直存在/*** 使用@Retension元注解,修饰普通的注解* 作用:规定普通注解的生命周期*/
    //@Retention(RetentionPolicy.SOURCE) 表示我们的注解只在源码阶段存在,编译成字节码后删除
    //@Retention(RetentionPolicy.CLASS) 表示我们的注解在源码和字节码阶段都存在,运行时删除
    @Retention(RetentionPolicy.RUNTIME) 表示我们的注解一直存在
    public @interface Anno2 {}
    
10.注解的解析
就是通过代码,读取某个位置上注解的属性值注解解析的固定步骤:a.获取注解所在的Class对象b.获取注解所在的具体目标(Field,Method,Constructor)c.判断目标是否真的有此注解d.从目标上获取我们要的注解e.从注解上获取其各个属性值   /*** 自定义注解:书注解*/
@Retention(RetentionPolicy.RUNTIME) -- 设置Book注解的生命周期是一直存在
public @interface Book {String name();double price();int pages();String[] authors();
}        public class Pig {private int age;public Pig(int age) {this.age = age;}@Book(name = "三国演义",price = 199.99,pages = 1001,authors = {"曹雪芹","罗贯中","吴承恩","施耐庵"})public void eat() {}
}public class TestDemo {public static void main(String[] args) throws NoSuchMethodException {//        注解解析的固定步骤:
//        a.获取注解所在的Class对象Class pigClass = Pig.class;
//        b.获取注解所在的具体目标(Field,Method,Constructor)Method eatMethod = pigClass.getMethod("eat");
//        c.判断目标是否真的有此注解boolean b = eatMethod.isAnnotationPresent(Book.class);if (b) {//        d.从目标上获取我们要的注解Book book = eatMethod.getAnnotation(Book.class);
//        e.从注解上获取其各个属性值System.out.println("书名:" + book.name());System.out.println("价格:" + book.price());System.out.println("页数:" + book.pages());System.out.println("作者们:" + Arrays.toString(book.authors()));} else {System.out.println("该方法上没有此注解");}}
}
11.综合练习_模拟Junit的@Test注解
需求: 编写一个注解,模拟Junit的@Test注解功能(使用main方法来代替右键执行)/*** 自定义注解,模拟Junit的@Test注解*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest {}public class Demo {@MyTestpublic void test01() {System.out.println(11111);}@MyTestpublic void test02() {System.out.println(22222);}@MyTestpublic void test03() {System.out.println(33333);}@MyTestpublic void test04() {System.out.println(44444);}
}public class TestDemo {public static void main(String[] args) throws Exception {//1.获取目标类的字节码文件对象Class clazz = Demo.class;//2.获取目标类上所有的成员方法Method[] methods = clazz.getMethods();//3.遍历判断for (Method method : methods) {//4.判断该方法上是否有注解if (method.isAnnotationPresent(MyTest.class)) {//5.执行该方法method.invoke(new Demo());}}}
}

第三章 动态代理

1.代理模式介绍
代理设计模式:被代理对象,没有能力或者不愿意完成某件事情,找有一个代理对象,由代理对象去完成作用:就是对被代理对象的功能进行增强
2.动态代理概述
底层通过反射技术,动态地(在运行时,需要时)生成被代理对象的代理对象
3.案例引出
/*** 学校提供的教师服务*/
public interface SchoolService {String login(String loginName, String passWord);String getAllClazzs();
}/*** 学校提供的教师服务的实现类*/
public class SchoolServiceImpl implements SchoolService {/*** 登录服务*/@Overridepublic String login(String loginName, String passWord) {try {Thread.sleep(new Random().nextInt(5000));} catch (InterruptedException e) {e.printStackTrace();}return "恭喜您,登录成功...";}/*** 查询班级服务*/@Overridepublic String getAllClazzs() {try {Thread.sleep(new Random().nextInt(5000));} catch (InterruptedException e) {e.printStackTrace();}return "1班,2班,3班";}
}public class TestDemo {public static void main(String[] args) {//1.创建一个实现类对象SchoolServiceImpl service = new SchoolServiceImpl();//2.登录String result = service.login("laowang123", "gebi123");System.out.println(result);//3.查询班级String allClazzs = service.getAllClazzs();System.out.println(allClazzs);}
}
4.使用动态代理优化代码
public class TestDemo {public static void main(String[] args) {//1.为学校的服务实现类,创建一个动态代理/*** Java提供创建代理对象的方法* Proxy.newProxyInstance(*      参数1:当前类的类加载器 基本上固定: 当前类.class.getClassLoader()*      参数2:被代理对象所有实现的接口字节码对象数组 new Class[]{接口1.class,接口2.class..}*      参数3:处理接口的实现类对象(处理类对象)* );*/SchoolService serviceProxy = (SchoolService)Proxy.newProxyInstance(TestDemo.class.getClassLoader(), new Class[]{SchoolService.class}, new InvocationHandler() {/*** 当我们调用动态代理对象的方法时,动态代理对象,会通过反射,把调用的方法,以及方法的参数封装起来* @param proxy 其实就是代理对象* @param method 通过代理对象调用的方法* @param args 通过带俩对象调用方法时传入的参数* @return* @throws Throwable*/public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {long start = System.currentTimeMillis();Object result = method.invoke(new SchoolServiceImpl(),args);long end = System.currentTimeMillis();System.out.println("耗时:"+(end-start)+"毫秒");return result;}});//2.调用动态代理对象的方法
//        String result = serviceProxy.login("1111", "2222");
//        System.out.println(result);
//String allClazzs = serviceProxy.getAllClazzs();System.out.println(allClazzs);}
}

第四章 JDK8新特性

Lambda
Stream
1. 方法引用
  • 方法引用介绍

    允许开发者可以直接引用现有的方法,来代理函数式接口的匿名内部类(Lambda)
    
  • 方法引用四种方式

    a.通过对象名,引用对象中成员方法对象名::成员方法名
    b.通过类名,直接引用类中的静态方法类名::静态方法名
    c.引用类的构造器类名::new
    d.引用数组的构造器数据类型[]::new
    
  • 基于静态方法引用的代码演示

    public class TestDemo {public static void main(String[] args) {//调用方法
    //        method(new 接口的实现类对象());
    //        method(new Consumer<String>() {//            @Override
    //            public void accept(String s) {//                System.out.println(s);
    //            }
    //        });
    //        method(s -> System.out.println(s));//使用方法引用method(System.out::println);//回顾:Stream<String> stream = Stream.of("jack", "rose", "tom", "jerry");
    //        stream.forEach(new Consumer<String>() {//            @Override
    //            public void accept(String s) {//                System.out.println(s);
    //            }
    //        });
    //        stream.forEach(s -> System.out.println(s));stream.forEach(System.out::println);}public static void method(Consumer<String> con) {con.accept("java");}
    }
    
2. Base64
  • Base64介绍

    一种编码技术
    
  • Base64内嵌类和方法描述

    Base64.EnCoder和Base64.DeCoder
    Base64.MimeEnCoder和Base64.MimeDeCoder
    Base64.URLEnCoder和Base64.URLDeCoder
    
  • Base64代码演示

    
    public class Base64Demo {public static void main(String[] args) {//1.EnCoder和DeCoderBase64.Encoder encoder = Base64.getEncoder();String encodeToString = encoder.encodeToString("中国HelloWorld我爱你".getBytes());System.out.println("编码之后的字符串:"+encodeToString);Base64.Decoder decoder = Base64.getDecoder();byte[] bs = decoder.decode(encodeToString);System.out.println("解码之后的字符串:" + new String(bs));System.out.println("--------------");//2.MIME类型编码和解码String encodeToString1 = Base64.getMimeEncoder(4,"-".getBytes()).encodeToString("中国HelloWorld我爱你".getBytes());System.out.println("编码之后的字符串:"+encodeToString1);byte[] bs1 = Base64.getMimeDecoder().decode(encodeToString1);System.out.println("解码之后的字符串:" + new String(bs1));//3.URLEnCoder和URLDeCoderSystem.out.println("--------------");byte[] bs2 = Base64.getUrlEncoder().encode("http://www.itheima.com".getBytes());System.out.println("编码之后的字符串:"+new String(bs2));byte[] bytes = Base64.getUrlDecoder().decode(bs2);System.out.println("解码之后的字符串:"+new String(bytes));//UUID 生成一个32个长度的全球唯一字符串UUID uuid = UUID.randomUUID();System.out.println(uuid);}
    }
    
总结
"能够通过反射技术获取Class字节码对象
"能够通过反射技术获取构造方法对象,并创建对象。
"能够通过反射获取成员方法对象,并且调用方法。
能够通过反射获取属性对象,并且能够给对象的属性赋值和取值。
"能够说出注解的作用编译检查
"能够自定义注解和使用注解public @interface 注解名{数据类型 属性名();数据类型只能是三大类: 基本类型,四个引用类型(String),以上12个一维数组}@注解名(属性名="具体的值",....)特殊value能够说出常用的元注解及其作用@Target@Rentetion
"能够解析注解并获取注解中的数据a.获取Classb.获取具体对象(Method,Constructor,Field)c.判断 isAnnotaionPresent(注解名.class);d.取出 getAnnotaion(注解名.class);e.获取注解中的属性值 注解对象.属性名();
能够完成注解的MyTest案例能够说出动态代理模式的作用
能够使用Proxy的方法生成代理对象
能够使用四种方法的引用(建议观看课后扩展视频_方法引用完整版)
能够使用Base64对基本数据、URL和MIME类型进行编解码

反射、注解、动态代理、JDK8新特性相关推荐

  1. 面试准备——Java回顾:高级编程(多线程、常用类、集合、泛型、IO流、反射、动态代理、新特性)

    多线程 程序.进程.线程 程序:完成特定任务.用某种语言编写的一组指令的结合,一段静态的代码,静态对象: 进程:程序的一次执行过程,即正在执行的程序: 线程:进程可细化为线程,是一个程序内部的一条执行 ...

  2. 死磕java底层(三)—反射、动态代理和注解

    1.反射介绍 1.1反射 反射是指程序可以访问,检测,修改它本身状态或行为的一种能力. 1.2java的反射机制 java的反射机制是指在程序运行状态中,给定任意一个类,都可以获取到这个类的属性和方法 ...

  3. JDK8新特性之重复注解

    转载自 JDK8新特性之重复注解 什么是重复注解 下面是JDK8中的重复注解( java.lang.annotation.Repeatable)定义的源码. @Documented @Retentio ...

  4. Android APP热更新中的插件化(Hook技术:反射或动态代理),Demo (2)

    修改AAPT,资源分区,用于Android插件化- https://github.com/BaoBaoJianqiang/AAPT -- Android下的挂钩(hook)和代码注入(inject) ...

  5. JDK8新特性知识点总结

    一个简洁的博客网站:http://lss-coding.top,欢迎大家来访 学习娱乐导航页:http://miss123.top/ 1. Open JDK 和 Oracle JDK Java 由 S ...

  6. 【JDK8新特性】之Lambda表达式

    目录 Lambda表达式 1. 需求分析 2.Lambda表达式初体验 3. Lambda的语法规则 3.1 Lambda练习1 3.2 Lambda练习2 4. @FunctionalInterfa ...

  7. 【JavaSE之JDK8新特性】三万字详文带你了解JDK8新特性

    JDK8新特性 一.Lambda 1.1需求分析 2.Lambda表达式的初级体验 3.Lambda表达式的语法规则 3.1.Lambda练习1 3.2.Lambda表达式练习2 4.Function ...

  8. JDK8新特性详解Lambda、StreamAPI、Optional等

    JDK8学习笔记 学习视频地址:https://www.bilibili.com/video/BV1k64y1R7sA 操作代码:https://gitee.com/rederic/study-jdk ...

  9. 集合框架,JDK8新特性

    一.集合框架 1.为什么会有集合? 集合和数组都是java中提供的可以用来存储多个数据的一种容器.由于数组类型特点是存储同一类型的元素且长度固定,可以存储基本数据类型值.为了满足现实需求, Java中 ...

最新文章

  1. 判断一个字符串中的字符是否唯一
  2. linux命令上常用命令
  3. 关于KVM的几篇细节文档
  4. 借助Redis完成延时任务
  5. 使用 vue-i18n 切换中英文
  6. Chapter 4 Invitations——25
  7. 图解Kafka,一看就明白!
  8. codevs1521 华丽的吊灯
  9. mysql 批量建表_mysql 如何实现循环批量插入?
  10. php 转换为自定义类,PHP面向对象教程之自定义类_PHP
  11. ROS无人机自主飞行(数传与串口)与PX4配置问题
  12. 虚拟机WIN7系统 如何设置网络
  13. codeigniter配置
  14. 农用化学活性成分的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  15. 【火电机组、风能、储能】高比例风电电力系统储能运行及配置分析(Matlab代码实现)
  16. android studio连接雷电模拟器
  17. winform图片标尺控件
  18. uni-app开发微信小程序常见问题(更新版):uni.getUserProfile要怎么写?uni.login和uni.getUserProfile的顺序?
  19. python 微信机器人 关键词_python-微信机器人之词云
  20. 圣诞树 圣诞树 圣诞树_Excel圣诞树2015

热门文章

  1. 携转待生效用户是什么_携号转网是什么意思
  2. 微信公众号扫描带参数二维码实现自动分组
  3. nlp-with-transformers系列-04_多语言命名实体识别
  4. 年历显示系统,输入一个年份,输出是在屏幕上显示该年的日历。
  5. Android异常篇 The option setting ‘android.disableResourceValidation=true‘ is experimental and unsupport
  6. oracle创建用户表空间6,Oracle创建表空间,添加用户及授权
  7. 基于人体各种调节机制的仿生人体机器人处理机制(空想)
  8. 车间设备联网与MES系统解决方案
  9. python在线翻译小程序_Python3.6实现带有简单界面的有道翻译小程序
  10. 生成式对抗网络(GAN)(李宏毅2022)