java反射基础
文章目录
前言
java的反射提供用于获取有关类和对象的反射信息的类和接口。
reflection允许以编程方式访问有关已加载类的字段、方法和构造函数的信息,以及使用反射字段、方法和构造函数在封装和安全限制内对其底层对应项进行操作。
一、创建一个简单类
package fanshe;
public class Cat {
public String name;
public int age;
//无参构造
Cat(){
}
//带参构造
public Cat(String name,int age){
this.name=name;
this.age=age;
}
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;
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
二、加载类 获取class对象
获取class对象的三种方式
1、通过 类名.class 直接获取
Class c1 = Cat.class;
System.out.println(c1.getName()); //全类名 包名+类名
System.out.println(c1.getSimpleName()); //简名——类名
打印结果分别是全包名、类名
2、调用Class提供的方法
Class<?> c2 = Class.forName("fanshe.Cat");
System.out.println(c2); //打印包名+类名
3、Object提供的方法
Cat cat = new Cat();
Class c3 = cat.getClass();
System.out.println(c3); //打印包名+类名
三、获取类的构造器
1.获取所有构造器
获取所有构造器的方法有两个:
getDeclaredConstructors——获取全部构造器,只要存在就能拿
getConstructors——获取全部构造器只能拿public修饰的
package fanshe;
import java.lang.reflect.Constructor;
public class Demo2 {
public static void main(String[] args) {
//1、获取类的class对象
Class c = Cat.class;
//2、获取所有构造器
Constructor[] dc = c.getDeclaredConstructors(); //获取全部构造器——只要存在就能拿
// Constructor[] dc = c.getConstructors(); //获取全部构造器——只能拿public修饰的
for (Constructor constructor : dc) {
System.out.println(constructor+"---->"+constructor.getName()+"----->"+constructor.getParameterCount());
}
}
}
2.获取无参构造器
getDeclaredConstructor——获取某个构造器,只要存在就能拿
getConstructors——获取某个构造器,只能拿public修饰的
Constructor dc1 = c.getDeclaredConstructor();
System.out.println(dc1+"---->"+dc1.getName()+"----->"+dc1.getParameterCount());
3.获取带参构造器
Constructor dc2 = c.getDeclaredConstructor(String.class, int.class);
System.out.println(dc2+"---->"+dc2.getName()+"----->"+dc2.getParameterCount());
4.获取构造器的作用
获取构造器的作用:初始化对象并返回
//3、获取无参构造器
Constructor dc1 = c.getDeclaredConstructor();
// System.out.println(dc1+"---->"+dc1.getName()+"----->"+dc1.getParameterCount());
dc1.setAccessible(true); //禁止检查访问权限——暴力反射
Cat cat = (Cat)dc1.newInstance();
// System.out.println(cat);
//4、获取有参构造
Constructor dc2 = c.getDeclaredConstructor(String.class, int.class);
// System.out.println(dc2+"---->"+dc2.getName()+"----->"+dc2.getParameterCount());
Cat cat1 = (Cat)dc2.newInstance("加菲", 2);
System.out.println(cat1);
四、获取类的成员变量
//5、获取成员变量
Field[] dfs = c.getDeclaredFields();
for (Field df : dfs) {
System.out.println(df.getName()+" ----> "+df.getType());
}
//6、获取某个成员变量
Field fname = c.getDeclaredField("name");
System.out.println(fname.getName()+" ----> "+fname.getType());
获取成员变量的作用:赋值、取值
//6、获取某个成员变量
Field fname = c.getDeclaredField("name");
// System.out.println(fname.getName()+" ----> "+fname.getType());
Field fage = c.getDeclaredField("age");
Cat cat2 = new Cat();
// fname.setAccessible(true); // 作用:禁止检查访问权限——暴力反射
// fage.setAccessible(true);
//赋值
fname.set(cat2,"机器猫");
fage.set(cat2,3);
System.out.println(cat2);
//取值
String name = (String)fname.get(cat2);
System.out.println(name);
五、获取类的成员方法
//7、获取所有成员方法
Method[] dm = c.getDeclaredMethods();
for (Method method : dm) {
// System.out.println(method.getName()+"---->"+method.getParameterCount()+"---->"+method.getReturnType());
}
//8、获取某个方法
// Method dm1 = c.getDeclaredMethod("run"); //无参
Method dm1 = c.getDeclaredMethod("eat",String.class); //带参
System.out.println(dm1.getName()+"---->"+dm1.getParameterCount()+"---->"+dm1.getReturnType());
获取成员方法的作用:执行
//9、成员方法的作用
run.setAccessible(true);
Cat cat3 = new Cat();
Object invoke = run.invoke(cat3); //调用无参方法 用cat触发
// System.out.println(invoke);
eat.setAccessible(true);
String invoke1 = (String)eat.invoke(cat3, "鱼"); //调用带参方法
System.out.println(invoke1);
六、总结
反射的作用
1、基本作用:可以得到一个类的全部成分然后操作
2、破坏封装性:可以获取私有的构造器、成员变量、成员方法,暴力反射;
3、最重要的用途:适合做Java的框架,基本上主流的框架都会基于反射设计出一些通用的功能