反射
date:2022/03/01
啥是反射
动态语言可以运行时改变自身结构
java通过反射可以变为准动态语言,但也增加了不安全性。
Class类用来管理反射。
应用
动态代理
在运行时判断对象所属的类
在运行时构造一个类的对象
在运行时判断一个类所有的变量和方法
在运行是调用一个对象的方法
优缺点
优点:可以动态创建编译对象
缺点:性能较弱。反射是一种解释操作,让jvm来操作。
Class类
每个类编译完成时候,都会产生Class对象。
反射获取类实际例子,一般有三种方式
1.Class.forname(“类路径”);
2.Class classTest = 目标类.class
3.Class classTest = 目标类实例对象.getClass()
类加载步骤:
- 1.方法区里面加载一个类对应Class对象
- 2.然后程序栈里面进行link过程
- 3.初始化
通过reflection获得一个对象
例子:
package com.day301.reflectiondemo;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test09 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
Class c1 =Class.forName("com.day301.reflectiondemo.Userme");
Constructor constuctor = c1.getDeclaredConstructor(String.class,int.class,double.class);
//通过构造器调用对象有参构造方法,生成对象
Userme user01 = (Userme) constuctor.newInstance("shi",01,59.63);
System.out.println(user01.getAge());
Userme c2 = (Userme)c1.newInstance();
System.out.println(c2);
//默认生成无参构造方法
Method method = c1.getDeclaredMethod("setAge", double.class);
method.invoke(c2, 37.09);
System.out.println(c2.getAge());
//返回一个method,注意的是,需要将方法invoke初始化
Userme c3 = (Userme)c1.newInstance();
Field name =c1.getDeclaredField("name");
name.setAccessible(true);
name.set(c3, "我要调用方法"
+ "没错哦");
System.out.println(c3.getName());
//update field方法,需要注意的是,需要添加setAccessible(True),private filed才能修改
}
}
结果:
59.63
com.day301.reflectiondemo.Userme@3dfc5fb8
37.09
我要调用方法没错哦
性能
package com.day301.reflectiondemo;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test10 {
public static void test01(){
Userme user = new Userme();
long starttime =System.currentTimeMillis();
for(int i=0;i<1000000000;i++) {
user.getName();
}
long endTime =System.currentTimeMillis();
System.out.println("默认方法"+(starttime-endTime)+"ms");
}
public static void test02() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Userme user = new Userme();
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("这是正常反射操时间: "+(starttime-endTime)+"ms");
}
public static void test03() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Userme user = new Userme();
Class c2 =user.getClass();
Method getName =c2.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(starttime-endTime+"ms");
}
public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
test01();
test02();
test03();
}
}
结果:
默认方法-3ms
这是正常反射操时间: -1196ms
-868ms
泛型
public class TestFanxing {
public void test01(Map<String , Userme> map,List<Userme> list) {
System.out.println("调用了Test01方法");
}
public Map<String ,Userme> test02(){
System.out.println("调用了Test02方法");
return null;
}
public static void main(String[] args) throws NoSuchMethodException, SecurityException {
{Method method = TestFanxing.class.getMethod("test01", Map.class,List.class);
System.out.println(method);
Type[] genericParameterTypes = method.getGenericParameterTypes();
for(Type genericParameterType : genericParameterTypes) {
System.out.println(genericParameterType);
if(genericParameterType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
for(Type actual:actualTypeArguments) {
System.out.println(actual);
}
}
}}
{Method method2 = TestFanxing.class.getMethod("test02", null);
System.out.println(method2);
Type[] genericParameterTypes = method2.getGenericParameterTypes();
for(Type genericParameterType : genericParameterTypes) {
System.out.println(genericParameterType);
if(genericParameterType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
for(Type actual:actualTypeArguments) {
System.out.println(actual);
}
}
}
}
}
}
public void com.day301.reflectiondemo.TestFanxing.test01(java.util.Map,java.util.List)
java.util.Map<java.lang.String, com.day301.reflectiondemo.Userme>
class java.lang.String
class com.day301.reflectiondemo.Userme
java.util.List<com.day301.reflectiondemo.Userme>
class com.day301.reflectiondemo.Userme
public java.util.Map com.day301.reflectiondemo.TestFanxing.test02()
注解与反射映射成ORM
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Field;
public class Test {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException {
Class c1 = Class.forName("com.total.day301.Student");
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
TableLipp tableLipp = (TableLipp) c1.getAnnotation(TableLipp.class);
String value = tableLipp.value();
System.out.println(value);
Field f =c1.getDeclaredField("id");
FieldLipp annotation = f.getAnnotation(FieldLipp.class);
System.out.println(annotation.columnName());
System.out.println(annotation.type());
System.out.println(annotation.length());
}
}
package com.total.day301;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@TableLipp("db_student")
public class Student {
@FieldLipp(columnName="db_id",type="int",length=10)
private int id;
@FieldLipp(columnName="db_age",type="int",length=10)
private int age;
@FieldLipp(columnName="db_name",type="varchar",length=10)
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student [id=" + id + ", age=" + age + ", name=" + name + "]";
}
public Student(int id, int age, String name) {
super();
this.id = id;
this.age = age;
this.name = name;
}
public Student() {
}
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface TableLipp{
String value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldLipp{
String columnName();
String type();
int length();
}
result:
@com.total.day301.TableLipp(value="db_student")
db_student
db_id
int
10