Python微信订餐小程序课程视频
https://edu.csdn.net/course/detail/36074
Python实战量化交易理财系统
https://edu.csdn.net/course/detail/35475
CommonsCollection1
1、前置知识
1.1、反射基础知识
1.1.1、 对象与类的基础知识
类(class),对象(object)
对象是类的实例化,中华田园犬(object)是狗(class)的实例化
类是对象的抽象化,狗(class)是中华田园犬(object)抽象化
1.1.2、反射获取对象过程
1、我们可以通过以下三种方法获取Class对象类型
Class classType = String.class;
Class classType = new String().getClass();/*new String()是一个对象*/
Class classType = Class.forName("java.lang.String");
2、在Class类中包含着很多方法函数,其中在本章节使用最频繁的就是
getName():获得类的完整名字。
getFields():获得类的public类型的属性。
getDeclaredFields():获得类的所有属性。
getMethods():获得类的public类型的方法。
getDeclaredMethods():获得类的所有方法。
getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes参数指定方法的参数类型。
getConstrutors():获得类的public类型的构造方法。
getConstrutor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes参数指定构造方法的参数类型。
newInstance():通过类的不带参数的构造方法创建这个类的一个对象。
2、通过默认构造方法创建一个新的对象,即先调用Class类的getConstructor()方法获得一个Constructor对象,它代表默认的构造方法,然后调用Constructor对象的newInstance()方法构造一个实例。(此处new Class[]{}、new Object[]{}表示空参数,既调用默认的无参数的构造方法)
Object objectCopy=classType.getConstructor(new Class[]{}).newInstance(new Object[]{});
3、获得对象的所有属性,即通过Class类的getDeclaredFields()方法返回类的所有属性,包括public、protected、default和private访问级别的属性
Field fields[]=classType.getDeclaredFields();
4、获得每个属性相应的get/set方法,然后执行这些方法,把原来的对象属性拷贝到新的对象中。
这里我们可以写一个InvokeTester的类,然后运用反射机制调用一个InvokeTester对象的add()方法(自定义方法),如add()方法的两个参数为int类型,那么获取表示add()方法的Method对象代码如下:
Method addMethod=classType.getMethod("add",new Class[]{int.class,int.class});
5、反射调用addMethod方法
//获得和属性对应的getXXX()方法
Method getMethod=classType.getMethod(getMethodName,new Class[]{});
//获得和属性对应的setXXX()方法
Method setMethod=classType.getMethod(setMethodName,new Class[]{field.getType()});
//具体实施(第四点描述)
Method addMethod=classType.getMethod("add",new Class[]{int.class,int.class});
//调用原对象的getXXX()方法
Object value=getMethod.invoke(object,new Object[]{});
System.out.println(fieldName+":"+value);
//调用拷贝对象的setXXX()方法
setMethod.invoke(objectCopy,new Object[]{value});
addMethod.invoke()
6、具体一个小例子
首先有个Users类,他有属性名字(name)、年龄(age)和会算加法()
public class Users {
String name;
int age;
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 int add(int num1, int num2){
int addnum= num1+num2;
return addnum;
}
}
那么我们反射获取他的某一个user对象的名字、年龄和加法
第一反射获取多参数的方法add
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) throws Exception {
//反射获取类对象类型,这里获取的是Users类对象类型
Class users = Class.forName("Users");
//类对象类型实例化,,即先调用Class类的getConstructor()方法获得一个Constructor对象,它代表默认的构造方法,然后调用Constructor对象的newInstance()方法构造一个实例。(此处new Class[]{}、new Object[]{}表示空参数,既调用默认的无参数的构造方法)
Object user = users.getConstructor(new Class[]{}).newInstance(new Object[]{});
//反射获取指定的类对象类型的add方法,add方法需要两个参数,参数类型为int型,getMethod类型的第二个参数必须是Class对象类型
Method add = users.getMethod("add", new Class[]{int.class, int.class});
//add方法反射调用(invoke)user对象,并且传入add方法的俩个参数值,invoke方法的参数必须是object对象
Object num = add.invoke(user, new Object[]{1, 2});
System.out.println((Integer) num);
}
}
反射调用单参数的方法setName和无参数方法getName
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) throws Exception {
/*
//反射获取类对象类型,这里获取的是Users类对象类型
Class users = Class.forName("Users");
//类对象类型实例化,,即先调用Class类的getConstructor()方法获得一个Constructor对象,它代表默认的构造方法,然后调用Constructor对象的newInstance()方法构造一个实例。(此处new Class[]{}、new Object[]{}表示空参数,既调用默认的无参数的构造方法)
Object user = users.getConstructor(new Class[]{}).newInstance(new Object[]{});
//反射获取指定的类对象类型的add方法,add方法需要两个参数,参数类型为int型,getMethod类型的第二个参数必须是Class对象类型
Method add = users.getMethod("add", new Class[]{int.class, int.class});
//add方法反射调用(invoke)user对象,并且传入add方法的俩个参数值,invoke方法的参数必须是object对象
Object num = add.invoke(user, new Object[]{1, 2});
System.out.println((Integer) num);
*/
Class users = Class.forName("Users");
Object zhangsan = users.getConstructor(new Class[]{}).newInstance(new Object[]{});
//反射获取Users类的setName()方法 ,需要传入setName的所需的参数类型,此处为String.class类型
Method setName = users.getMethod("setName", new Class[]{String.class});
//反射设置zhangsan对象实例的名字为张三
setName.invoke(zhangsan,new Object[]{"张三"});
//反射获取Users类的getName()方法,需要传入getName的参数类型,此处为空
Method getName = users.getMethod("getName", new Class[]{});
//反射获取zhangsan对象实例的名字
Object Name = getName.invoke(zhangsan);
System.out.println((String) Name);
}
}
1.1.3、反射的基本用法
反射又有很多琐碎的点,这里只讲它的基本用法如果当前拥有一个对象的话,那么可以动态的调用该对象的所有方法
// Step1 获取Class对象
Class cls = obj.getClass();
// Step2 获取想要的方法对象
Method mth = cls.getMethod("MethodName",new Class[]{arg1_type,arg2_type});
// Step3 调用方法
mth.invoke(obj,new Object[]{arg1,arg2})
这里注意的是getMethod的第二个参数为Class数组,Class的概念我们之前也提到过。
1.2、动态代理知识
动态代理需要理解反射包的三个类
反射包 java.lang.reflect 的三个类:InvocationHandler,Method,Proxy
InvocationHandler
这个类其实就一个方法就是invoke方法,该方法用代理商在不改变代理对象的情况,需要添加的功能
参数:
Object proxy:jdk的代理类,无需赋值
Method method:代理对象的方法,jdk提供的Method的对象
Object[] args:代理对象的方法执行的参数
package java.lang.reflect;
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
Method
Method方法主要在InvocationHandler的invoke方法中实现,表示执行代理对象的方法
Method.invoke(目标的对象,方法的参数)
Proxy
newProxyInstance的方法的三个参数为
ClassLoader loader:类加载器,负责向内存中加载对象的。使用反射获取的
Class [] interfaces :目标对象实现的接口,也是反射获取的
InvocationHandler h:我们自己写的,代理需要完成的功能
举个具体里的例子(Usb)
首先实现一个统一的买usb的接口,里面有一个卖usb的方法
public interface Usbsell {
float sell(int acount);
}
金士顿厂家要卖usb,所以继承这个接口,他买85元
package com.akkacloud.factory;
import com.akkacloud.service.Usbsell;
public class UsbKingFactor implements Usbsell {
@Override
public float sell(int acount) {
return 85.0f;
}
}
我们是一个商店,去买我们要赚差价
第一种写法,直接在主函数中创建我们的InvocationHandler接口
package com.akkacloud;
import com.akkacloud.factory.UsbKingFactor;
import com.akkacloud.handler.MysellHandler;
import com.akkacloud.service.Usbsell;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.refl