java反射学习
反射学习
类知识
- 一个类在内存中只有一个Class对象,创建的对象可以通过hashCode进行判定
- 一个类被加载后,类的整体结构都会被封装在Class对象中
哪些类型可以有Class对象
-
class:外部类、成员(成员内部类、静态内部类)、局部内部类、匿名内部类
-
interface:接口
-
[]:数组
-
enum:枚举
-
annotation:注解
-
primitive type:基本数据类型
-
void
Class c1 = Object.class; //对象 Class c2 = Comparable.class; //接口 Class c3 = String [].class; //一维数组 Class c4 = int [][].class; //二维数组 Class c5 = Override.class; //注解 Class c6 = ElementType.class; //枚举 Class c7 = Integer.class; //基本数据类型 Class c8 = void.class; //void Class c9 = Class.class; //Class
获得Class类的方式
-
使用对象.getClass()的方式,所有的都继承于Object类,Object类中存在getClass()方法
-
使用Class.forName("包路径.类名")获取
-
具体的类.class获取 -->最高效也是最安全的做法
-
基本内置类型的包装类都有TYPE属性,可直接通过.TYPE获取,例如Integer.TYPE得到int的Class
Person ps=new Student(); //获得Class类的方式1 Class ps1 = ps.getClass(); //获得Class类的方式2 Class<?> ps2 = Class.forName("com.lwp.reflect.Student"); //获得Class类的方式3 Class ps3 = Student.class; //基本内置类型的包装类都有Type属性 Class c4=Integer.TYPE;
Class类的常用方法
-
类信息获取
Person ps=new Person(); Class cl = ps.getClass(); //获取类的包名+类名 String name = cl.getName(); //获取类名 String simpleName = cl.getSimpleName(); -
字段获取
//获取指定的字段-->只能获取public的 Field age = cl.getField("name"); //获取指定的字段,可获取私有 Field age1 = cl.getDeclaredField("age"); //获取所有的public修饰的字段 Field[] fields = cl.getFields(); //获取所有的字段,含private Field[] declaredFields = cl.getDeclaredFields(); -
方法获取
//获取指定的无参方法,第二个参数为null即可 Method method = cl.getMethod("show",null); //获取指定的有参方法,参数个数根据方法的参数决定,参数类型为方法参数的class对象 Method age = cl.getDeclaredMethod("age", int.class); //获取本类的所有public方法以及父类的public方法 Method[] methods = cl.getMethods(); //只获取本类的所有方法 Method[] declaredMethods = cl.getDeclaredMethods(); -
构造方法获取
//获取类中所有的public构造方法 Constructor[] constructors = cl.getConstructors(); //获取类中所有的构造方法 Constructor[] declaredConstructors = cl.getDeclaredConstructors(); //获取类中无参的构造方法 Constructor constructor = cl.getConstructor(); //获取类中指定参数的构造方法 Constructor declaredConstructor = cl.getDeclaredConstructor(String.class, int.class);
使用反射操作类
Class cl = Class.forName("com.lwp.reflect.Person");
//通过newInstance调用类的无参构造方法创建对象
Person ps=(Person)cl.newInstance();
System.out.println(ps);
//通过构造函数指定参数创建对象
Constructor constructor = cl.getDeclaredConstructor(String.class, int.class);
//当操作私有构造方法、方法、属性时必须设置该值为true,表示无障碍阻挡
constructor.setAccessible(true);
//根据构造方法的数据类型传递对应的数据
Object person = constructor.newInstance("刘文蒲", 18);
System.out.println(person);
//操作类中的方法
Method method = cl.getDeclaredMethod("age", int.class);
method.setAccessible(true);
//调用方法并接收返回值:invoke需要的参数,参数1:操作的对象,参数..根据方法决定,无参不需要传
Object invoke = method.invoke(ps, 18);
System.out.println(ps);
System.out.println(invoke);
//操作类中的属性
Field field = cl.getField("name");
//参数为:参数1:需要操作的对象,参数1:给字段设定的值
field.set(ps,"刘文蒲");
System.out.println(ps);
被操作的Person类
public class Person {
public String name;
private String sex;
private int age;
int num;
public Person(){}
public Person(String name, String sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
private Person(String name, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public void show(){
System.out.println("我叫"+name);
}
private String age(int age){
this.age=age;
return "我叫"+name+"今年"+age+"岁";
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
", num=" + num +
'}';
}
}
使用反射操作泛型
获取泛型内的参数类型
Class cl = Person.class;
System.out.println("-------------参数泛型--------------");
Method method = cl.getDeclaredMethod("test01", Map.class, List.class,String.class);
//获取泛型参数类型
Type[] types = method.getGenericParameterTypes();
for (Type type : types) {
//判断参数是否是泛型
if(type instanceof ParameterizedType){
ParameterizedType pt=(ParameterizedType)type;
//获取泛型里的参数类型
Type[] actualTypeArguments = pt.getActualTypeArguments();
System.out.print(type+"----->");
for (Type on : actualTypeArguments) {
System.out.print(on+"\t");
}
System.out.println();
}
}
System.out.println("-------------返回值泛型--------------");
Method method2 = cl.getDeclaredMethod("test02", null);
//获取泛型返回值类型
Type genericReturnType = method2.getGenericReturnType();
if(genericReturnType instanceof ParameterizedType){
ParameterizedType on=(ParameterizedType)genericReturnType;
Type[] actualTypeArguments = on.getActualTypeArguments();
System.out.println(genericReturnType);
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
if(actualTypeArgument instanceof ParameterizedType){
ParameterizedType on1=(ParameterizedType)actualTypeArgument;
for (Type typeArgument : on1.getActualTypeArguments()) {
System.out.print(typeArgument+"\t");
}
}
}
}
使用反射操作泛型填充数据
----待补充
使用反射操作注解
定义注解相关类
自定义注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MzTable {
String value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MzColumn {
String value();
int length() default 50;
String type() default "varchar2";
}
类中使用注解
@MzTable("mz_Student")
public class Student extends Person{
@MzColumn(value = "mz_age",length = 3,type = "number")
private int age;
@MzColumn("mz_name")
private String name;
@MzColumn(value = "mz_sex",length = 4)
private String sex;
}
读取注解信息
Class cl = Student.class;
//获取类的指定注解
Annotation annotation = cl.getAnnotation(MzTable.class);
System.out.println(annotation);
//获取类的所有注解
Annotation[] annotations = cl.getAnnotations();
Field[] declaredFields = cl.getDeclaredFields();
for (Field declaredField : declaredFields) {
//获取字段上的指定注解
MzColumn mzColumn = declaredField.getAnnotation(MzColumn.class);
System.out.println(mzColumn);
//获取字段上的所有注解
declaredField.getAnnotations();
}
反射操作类封装
参考博客:https://blog.csdn.net/huangliniqng/article/details/88554510

浙公网安备 33010602011771号