一、反射的概念
java获取类信息的能力叫做反射
1.1、反射的创建方式:
1.Class.forName(“全类名”)
全类名是包名加类名
//Class.forName("全类名")
Class class1=Class.forName("com.qcby.Cat");
2.类名.class,类是静态的才能这么调用。
//类名.class
Class class2=Cat.class;
3.对象名.getClass,不确定是不是静态的
//对象名.getClass
Cat cat=new Cat();
Class class3=cat.getClass();
1.2、反射信息的获取
Cat类:
public class Cat {
public int age;
public String name;
public static String from;
private char sex;
protected String idCard;
String phone="";
public void run() {
System.out.println("-----");
}
private void eat(String name,char sex) {
System.out.println("*****");
}
private void eat(int age) {
}
public void hello(int age,char sex) {
}
void world() {
}
全局变量的获取:
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
//Class.forName("全类名")
Class class1=Class.forName("com.qcby.Cat");
//获取所有类的全局变量
Field[] fields=class1.getDeclaredFields();
for (Field field : fields) {
System.out.println(field);
}
System.out.println("----------");
//获取public修饰的全局变量
Field[] fields1=class1.getFields();
for (Field field : fields1) {
System.out.println(field);
}
System.out.println("-------");
//获取指定的全局变量
Field field=class1.getDeclaredField("sex");
System.out.println(field);
System.out.println("------------");
//获取指定的public修饰的全局变量
//Field field1 = class1.getField("sex"); X
//Field field1 = class1.getField("age"); V
//Field field1 = class1.getField("idCard"); X
//Field field1 = class1.getField("phone"); X
//System.out.println(field1);
}
方法的获取:
//Class.forName("全类名")
Class class1=Class.forName("com.qcby.Cat");
//获取所有类的方法
Method[] methods=class1.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method);
}
System.out.println("-------------");
//获取所有public修饰的方法
Method[] methods1=class1.getMethods();
for (Method method : methods1) {
System.out.println(method);
}
System.out.println("---------------");
//获取类中指定的方法
Method method=class1.getDeclaredMethod("eat",String.class,char.class);
System.out.println(method);
System.out.println("------------");
//获取类中指定的public修饰的方法
Method method1=class1.getMethod("hello", int.class,char.class);
System.out.println(method1);
}
构造器的获取:
Cat类:
public class Cat {
public int age;
public String name;
public static String from;
private char sex;
protected String idCard;
String phone="";
public Cat() {
}
public Cat(String name,int age) {
}
public Cat(String idCard) {
}
Cat(char sex){
}
}
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
//Class.forName("全类名")
Class class1=Class.forName("com.qcby.Cat");
//获取所有类的构造器
Constructor[] constructors=class1.getDeclaredConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
System.out.println("-----------");
//获取类的public类型的构造器
Constructor[] constructors1=class1.getConstructors();
for (Constructor constructor : constructors1) {
System.out.println(constructor);
}
System.out.println("-------------");
//获取指定的类的构造器
Constructor constructor=class1.getDeclaredConstructor(String.class,int.class);
System.out.println(constructor);
System.out.println("----------");
//获取指定的public类型的构造器
Constructor constructor1=class1.getConstructor(String.class);
System.out.println(constructor1);
}
1.3、利用信息操作类
1.3.1、取值赋值
创建对象就会给变量开辟存储空间,变量就可以存储值
取值get(obj)方法也需要传入对象
针对private类型的--我们不能直接设置值,我们需要暴力反射
Cat类:
public int age;
public String name;
public static String from;
private char sex;
protected String idCard;
String phone="";
private void eat(String name,int count) {
System.out.println(name+"能吃"+count+"碗");
}
public void run(int nums) {
System.out.println("我跑了"+nums+"米");
}
public Cat() {
}
public Cat(String name,int age) {
}
public Cat(String idCard) {
}
Cat(char sex){
}
1.3.2、给变量设置值
public static void main(String[] args) throws Exception {
//Class.forName("全类名")
Class class1 = Class.forName("com.qcby.Cat");
//获取变量,并给变量赋值
Field name = class1.getField("name");
System.out.println(name);
// 赋值 set(obj, value) // set(对象, 值)
// 取值 get(obj)
Cat cat = new Cat(); // 因为反射只能赋值,但是我们需要提前创建对象给全局变量分配内存空间
Cat cat1 = new Cat(); // 因为反射只能赋值,但是我们需要提前创建对象给全局变量分配内存空间
name.set(cat,"小花猫");
System.out.println(name.get(cat1));
System.out.println(name.get(cat));
System.out.println("------------以上是针对public类型的全局变量...................");
Field phone = class1.getDeclaredField("phone");
System.out.println(phone);
// 赋值 set(obj, value) // set(对象, 值)
// 取值 get(obj)
Cat cat2 = new Cat(); // 因为反射只能赋值,但是我们需要提前创建对象给全局变量分配内存空间
phone.set(cat2,"18310189962");
System.out.println(phone.get(cat2));
System.out.println("--------------以上是针对defult类型的全局变量.-----------------");
Field sex = class1.getDeclaredField("sex");
System.out.println(sex);
// 赋值 set(obj, value) // set(对象, 值)
// 取值 get(obj)
Cat cat3 = new Cat();
// 针对private类型----我们不能直接设置值。我们需要暴力反射
sex.setAccessible(true); //暴力反射
sex.set(cat3,'男');
System.out.println(sex.get(cat3));
System.out.println("--------------以上是针对private类型的全局变量,记住需要暴力反射.-----------------");
}
1.3.3、调用方法赋值
1.3.4、调用构造器获取对象
Constructor constructor = class1.getConstructor(String.class,int.class);
// newInstance()
Cat cat = (Cat) constructor.newInstance("张三",200);
System.out.println(cat);
System.out.println("----------------以上是针对public类型的方法----------------");
Constructor constructor2 = class1.getDeclaredConstructor(String.class);
constructor2.setAccessible(true);
Cat cat2 = (Cat) constructor2.newInstance("18658524599572");
System.out.println(cat2);
1.4、Tomcat怎么利用反射获取类的信息
tomcat在启动时会先去扫描固定文件夹下的所有文件
tomcat是servlet的容器