反射
1.什么是类对象:
所有的类,都存在一个类对象,这个类对象用于提供类本身的信息,比如有几种构造方法, 有多少属性,有哪些普通方法。
比方有一个Hero类:类对象就是用于描述这种类,都有什么属性,什么方法的。
获取类对象有3种方式
- Class.forName
- Hero.class
- new Hero().getClass()
在一个JVM中,一种类,只会有一个类对象存在。所以以上三种方式取出来的类对象,都是一样的。
注: 准确的讲是一个ClassLoader下,一种类,只会有一个类对象存在。通常一个JVM下,只会有一个ClassLoader。
2.获取类对象时 静态属性会被初始化 (除了直接使用 Class c = Hero.class 这种方式,这种方式不会导致静态属性被初始化)
public class TestReflection {
public static void main(String[] args) {
String className1 = "com.javaBasic.modelClass.Hero";
/*
*public class Hero {
public String name;
public float hp;
public int damage;
public int id;
static String copyright;
static {
System.out.println("初始化 copyright");
copyright = "版权由Riot Games公司所有";
}
}
* */
try {
Class pClass3=new Student().getClass();
Class pClass1=Class.forName(className1);
Class pClass2=Hero.class;
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
通过反射创建对象
反射是创建对象的另一种方式,通过反射创建类对象后 获取构造器将其实例化后,还可以通过field修改属性,调用方法
public class TestReflection {
public static void main(String[] args) {
String className1 = "com.javaBasic.modelClass.Hero";
try {
Class pClass1=Class.forName(className1);
Constructor constructor= pClass1.getConstructor();
Hero hero= (Hero) constructor.newInstance();
hero.name="通过反射创建类对象后 获取构造器将其实例化后的name";
System.out.println(hero);
Field f1= hero.getClass().getDeclaredField("name");
f1.set(hero,"修改后的name字段");
System.out.println(hero.name);
// 获取这个名字叫做setName,参数类型是String的方法
Method m = h.getClass().getMethod("setName", String.class);
// 对h对象,调用这个方法
m.invoke(h, "调用方法并set后的name");
// 使用传统的方式,调用getName方法
System.out.println(h.getName());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
注:
getField和getDeclaredField的区别
这两个方法都是用于获取字段
getField 只能获取public的,包括从父类继承来的字段。
getDeclaredField 可以获取本类所有的字段,包括private的,但是不能获取继承来的字段。 (注: 这里只能获取到private的字段,但并不能访问该private字段的值,除非加上setAccessible(true))
来一个实际一点的例子
public class Cat {
private static String name;
public Cat(){
name="雷猫咪";
}
private void play1(){
System.out.println("私有方法:和猫咪快乐的玩耍");
}
public void play2(){
System.out.println("公有方法:带着猫咪出去逛街");
}
}
public class Test {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, ClassNotFoundException {
Class reflect = Class.forName("com.example.javacore.reflection.demo1.Cat");
String name = reflect.getName();
System.out.println("获取到类名:"+name);
//动态创建类的对象
Object object = reflect.getConstructor().newInstance();
//调用方法
Method method = reflect.getDeclaredMethod("play1");
//注意这里是一个私有方法 所以设置其可访问性
method.setAccessible(true);
method.invoke(object);
}
}
获取到类名:com.example.javacore.reflection.demo1.Cat
私有方法:和猫咪快乐的玩耍
反射有什么用?
反射的用处很多 在框架中使用的比较广泛 java框架的很多便捷功能 它的底层实现往往都有放射的影子
比如:通常在Dao框架中,save方法都是泛型参数
save(T t)
save(People people)
save(User user)
为什么我们不管放什么对象都能保存到数据库呢
不管中间走了多少路 最后还是要执行这条语句的 insert into tablename values
问题的关键就是如何生成这个SQL 这就需要反射 取得这个类对应的信息 然后去找对应的数据库表了文章来源:https://www.toymoban.com/news/detail-449449.html
(看到这也能明白注解是什么用的了,注解其实就是class中的一些元数据信息,比如类的元数据信息,字段的元数据信息,这样在反射的时候可以拿到类到底对应的数据库中的哪个字段,哪个表名,这样才能生成正确的SQL)文章来源地址https://www.toymoban.com/news/detail-449449.html
到了这里,关于什么是反射机制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!