1.反射获取运行时类的完整结构
获取属性,方法,构造方法
package com.yang;
import javax.xml.transform.Source;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test10 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
Class c1 = Class.forName("com.yang.User");
// Class c1 = new User().getClass(); 等同于上面的
//1.获取属性值
Field name = c1.getDeclaredField("name"); //获取指定的属性
System.out.println(name);
Field number = c1.getField("number");//获取指定的public修饰的属性,私有的看不到
System.out.println(number);
Field[] fields = c1.getFields(); //只能找到public修饰的属性,私有的看不到
Field[] fields1 = c1.getDeclaredFields(); //获取全部的属性
for (Field field : fields) {
System.out.println(field);
}
//2.获取方法
System.out.println("==========获取方法===========");
Method getAge = c1.getMethod("getAge"); //获取指定的public方法
System.out.println(getAge);
Method[] methods = c1.getMethods(); //获取本类及父类的所有的public方法
for (Method method : methods) {
System.out.println(method);
}
System.out.println("====================");
//getDeclaredMethod()有参无参用于区分有参构造和无参构造
Method getAge1 = c1.getDeclaredMethod("getAge",null);//获取指定的方法,getAge()没有参数,不传就是null
Method setName = c1.getDeclaredMethod("setName", String.class);
System.out.println(getAge1);
System.out.println(setName);
System.out.println("-----------------------");
Method[] declaredMethods = c1.getDeclaredMethods(); //获取本类的所有的方法,包括私有的
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
Method enclosingMethod = c1.getEnclosingMethod();
System.out.println(enclosingMethod);
//3.获取构造方法
System.out.println("====================");
Constructor constructor = c1.getConstructor();
System.out.println(constructor);
Constructor declaredConstructor = c1.getDeclaredConstructor(String.class,int.class,int.class);//获取有参构造器
System.out.println(declaredConstructor);
//获取指定构造器
Constructor[] constructors = c1.getConstructors();
for (Constructor constructor1 : constructors) {
System.out.println(constructor1);
}
Constructor[] declaredConstructors = c1.getDeclaredConstructors();
for (Constructor declaredConstructor1 : declaredConstructors) {
System.out.println(declaredConstructor1);
}
}
}
2.动态创建对象执行方法
创建类的对象:调用Class对象的newInstance()方法
- 类必须要有一个无参构造器;
- 类的构造器的访问权限必须足够
如果没有无参构造,要在操作的时候明确调用类的构造器,并将参数传进去,才可以实例化操作
-
通过class类的getDeclaredConstructor()取得本类指定形参类型的构造器
-
传递的参数为对象数组
-
通过constructor实例化对象
package com.yang; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Test11 { public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { Class c1 = Class.forName("com.yang.User");//获得class对象 //构造一个对象 // User user = (User) c1.newInstance();//本质是调用了类的无参构造器 // System.out.println(user); //User{name='null', age=0, id=0} //通过构造器创建对象,可以没有无参构造 Constructor onstructor = c1.getDeclaredConstructor(String.class, int.class, int.class); User user2 = (User) onstructor.newInstance("zhangsan", 2, 4); System.out.println(user2); //通过反射调用普通方法 User user3 = (User) c1.newInstance(); /*通过反射获取一个方法 invoke(对象,”方法的值“):激活的意思 */ Method setName = c1.getDeclaredMethod("setName", String.class); setName.invoke(user3,"张三"); System.out.println(user3.getName()); //通过反射操作属性 User user4 = (User) c1.newInstance(); Field name = c1.getDeclaredField("name"); //不能直接操作私有属性,我们需要关闭程序的安全检测,属性或者方法的setAccessible(true) name.setAccessible(true);//方法,字段和构造器都有这个方法 name.set(user4,"张三2"); System.out.println(user4.getName()); } }
3.性能分析
普通方式调用
反射方式调用
放射方式调用 关闭检测
三种方式对比,处理数据的执行时间
package com.yang;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test12 {
//普通方式调用
public static void test01(){
User user = new User();
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
user.getName();
}
long endTime = System.currentTimeMillis();
System.out.println("普通方式执行10亿次:"+(endTime-startTime)+"ms");
}
//反射方式调用
public static void test02() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
User user = new User();
Class c1 = user.getClass();
Method getName = c1.getDeclaredMethod("getName", null);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
getName.invoke(user,null);
}
long endTime = System.currentTimeMillis();
System.out.println("反射方式执行10亿次:"+(endTime-startTime)+"ms");
}
//放射方式调用 关闭检测
public static void test03() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
User user = new User();
Class c1 = user.getClass();
Method getName = c1.getDeclaredMethod("getName", null);
getName.setAccessible(true);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
getName.invoke(user,null);
}
long endTime = System.currentTimeMillis();
System.out.println("关闭检测反射方式执行10亿次:"+(endTime-startTime)+"ms");
}
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
test01();
test02();
test03();
}
}
普通方式执行10亿次:5ms
反射方式执行10亿次:2406ms
关闭检测反射方式执行10亿次:1080ms
4.反射操作泛型
package com.yang;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
//通过反射获取泛型
public class Test13 {
public void test01(Map<String,User> map , List<User> list){
System.out.println("test01");
}
public Map<String,User> test02(){
System.out.println("test02");
return null;
}
public static void main(String[] args) throws NoSuchMethodException {
Method method01 = Test13.class.getDeclaredMethod("test01", Map.class, List.class);
Type[] genericParameterTypes = method01.getGenericParameterTypes();//获取泛型参数类型
for (Type genericParameterType : genericParameterTypes) {
System.out.println(genericParameterType);
System.out.println("遍历泛型中类型");
if(genericParameterType instanceof ParameterizedType){//判断是不是参数化类型
//获得真实的泛型参数信息,强转
Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
System.out.println("-------------------------------");
Method method02 = Test13.class.getMethod("test02", null);
Type genericReturnType = method02.getGenericReturnType();
if(genericReturnType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
}
5.获取注解信息
package com.yang;
import java.lang.annotation.*;
import java.lang.reflect.Field;
public class Test14 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class stu = Class.forName("com.yang.Stu");
Annotation[] annotations = stu.getAnnotations();
//通过反射获得注解
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
//获得注解的value值
System.out.println("-------------");
TableYang annotation = (TableYang) stu.getAnnotation(TableYang.class);
System.out.println(annotation.value());
//获得指定注解
Field name = stu.getDeclaredField("name");
FieldYang annotation1 = name.getAnnotation(FieldYang.class);
System.out.println(annotation1.columnName());
System.out.println(annotation1.length());
System.out.println(annotation1.type());
Field id = stu.getDeclaredField("id");
FieldYang annotation2 = id.getAnnotation(FieldYang.class);
System.out.println(annotation2.columnName());
System.out.println(annotation2.length());
System.out.println(annotation2.type());
}
}
@TableYang("db_stu")
class Stu{
@FieldYang(columnName="db_name",length = 3,type = "varchar")
private String name;
@FieldYang(columnName="db_age",length = 10,type = "int")
private int age;
@FieldYang(columnName="db_id",length = 10,type = "int")
private int id;
public Stu() {
}
public Stu(String name, int age, int id) {
this.name = name;
this.age = age;
this.id = id;
}
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 getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "Stu{" +
"name='" + name + '\'' +
", age=" + age +
", id=" + id +
'}';
}
}
//类名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface TableYang{
String value();
}
//属性的注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface FieldYang{
String columnName();
String type();
int length();
}
结果:
@com.yang.TableYang(value="db_stu")
-------------
db_stu
db_name
3
varchar
db_id
10
int
进程已结束,退出代码0