一、什么是反射?
①框架:就是一种半成品!好处:提高我们的开发效率,是我们的代码更加简洁
②反射:允许时把类中成员抽取为其他类的过程叫做反射
二、获取反射类Class的方法
①通过类的全路径字符串来获取
Class.forName("全路径")
例子:spring框架<bean id="" class="类的全路径">----可以获取类对象---Class----------类对象
②通过类名来获取
类名.class
例子:mybatis框架 session.getMapper(StudentDao.class);-----反射类对象获取对应的类对象
③通过对象类获取
对象名.getClass();
当知道该类的对象时,可以通过对象来获取反射类
public class demo01 {
public static void main(String[] args)throws Exception {
//获取Class类的方式
//(1)通过类的全类名字符串来获取。
Class aClass = Class.forName("com.ykq.Student");
//(2)通过类名来获取
Class bClass = Student.class;
//(3)对象
Student s=new Student();
Class cClass = s.getClass();
//思考: 上面这些方式获取到的Class对象的地址是否一样?
System.out.println(aClass==bClass); //==比较引用地址。
System.out.println(aClass==cClass);
System.out.println(bClass==cClass); //任何一个类的反射类对象只有一个。
}
}
class Student{
private String name;
private int age;
public void show(){
System.out.println("~~~~~~~show~~~~~~~~~~~");
}
public Student() {
}
}
三、通过反射类获取对应的类对象
public static void main(String[] args)throws Exception{
Class<Student> aClass=Student.class;//得到Student的反射类对象
Student student=aClass.newInstance();//通过反射类得到对应的类对象
System.out.println(student);
}
四、获取Field类的方式
getDeclaredField(String name):获取本类中指定属性名的Field对象
getDeclaredFields():获取本类中所有的属性对象
getField(String name):获取指定的public修饰的属性名的Field的对象(包含父类的属性)
getFields():获取所有public修饰的属性对象(包含父类的属性)
public static void main(String[] args) throws Exception {
System.out.println("===============获取指定public修饰的属性对象===========");
Class<?> aClass = Class.forName("com.ykq.demo3.Student");
Field nameField = aClass.getField("name"); //获取public指定的name属性对象
System.out.println(nameField);
Field sexField = aClass.getField("sex");
System.out.println(sexField);
System.out.println("==================获取本类中指定的属性对象=========================");
Field nameField2 = aClass.getDeclaredField("name");//获取本类中的属性对象
System.out.println(nameField2);
Field ageField2 = aClass.getDeclaredField("age");//获取本类中的属性对象
System.out.println(ageField2);
// Field sexField2 = aClass.getDeclaredField("sex");//获取本类中的属性对象
// System.out.println(sexField2);
System.out.println("===============获取全部public修饰的属性对象=================");
Field[] fields = aClass.getFields();
for (Field f:fields) {
System.out.println(f);
}
System.out.println("============获取本类中所有属性对象===================");
Field[] declaredFields = aClass.getDeclaredFields();
for (Field field:declaredFields) {
System.out.println(field);
}
}
五、Field类中的一些操作有哪些?
get(Object obj) 返回该所表示的字段的值Field .指定的对象上
get(Object obj,Object value) 为指定属性赋值
setAccessible(boolean) 设置属性的可见性
public class Test04 {
public static void main(String[] args)throws Exception {
Class<?> aClass = Class.forName("com.zd.demo4.Student");
Object o = aClass.newInstance();
Field nameField = aClass.getField("name");
System.out.println(nameField.get(o));//获取属性name的值
nameField.set(o,"张三"); //为name属性对象赋值
System.out.println(nameField.get(o));
Field ageField = aClass.getDeclaredField("age");
ageField.setAccessible(true);//设置私有属性的可见性,打破面向对象的封装性
ageField.set(o,15);//因为私有无法访问
System.out.println(o);
}
}
class Father{
public String sex;
}
class Student extends Father {
public String name;
private int age;
public void show(){
System.out.println("~~~~~~~show~~~~~~~~~~~");
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Student() {
}
}
六、获取方法类Method的方法:
getDeclaredMethod(String name,Class<?>... paramenterTypes):获取本类中指定方法名的方法对象
getDeclaredMethods():获取本类中所有的方法
getMethod(String name,Class<?>.. paramterTypes):获取指定类中public修饰的方法 包含父类
getMethods():获取所有的public方法
public class Test05{
public static void main(String[] args)throws Exception {
Class<Student> aClass = Student.class;
Student student = aClass.newInstance();
Method show = aClass.getMethod("show");
System.out.println(show);
Method print = aClass.getMethod("print",Integer.class,String.class);
System.out.println(print);
Method fun = aClass.getDeclaredMethod("fun");
System.out.println(fun);
//回调该方法---执行该方法。
show.invoke(student);//Object obj 对象名 Object... args:参数值
fun.setAccessible(true);//调用私有方法时需要设置可见性
fun.invoke(student);
Object o = print.invoke(student, 25, "中国");
Method toString = aClass.getMethod("toString");
Object invoke = toString.invoke(student);
System.out.println(invoke);
}
}
class Father{
public String sex;
public void print(Integer age,String address){
System.out.println("父类中print方法"+age+";address:"+address);
}
}//
class Student extends Father {
public String name;
private int age;
public void show(){
System.out.println("~~~~~~~show~~~~~~~~~~~");
}
private void fun(){
System.out.println("~~~~~~~fun~~~~~~~~~~~");
}
@Override
public String toString() {
return "Student{" +
"sex="+sex+
", name='" + name + '\'' +
", age=" + age +
'}';
}
public Student() {
}
}
七、获取构造类Constructor的方式:
getConstructor(类<?>... parameterTypes)
getConstructors()
该类Constructor中具有的方法:如果类中没有无参构造函数时
newInstance
public class Test06 {
public static void main(String[] args)throws Exception {
Class<Teacher> aClass = Teacher.class; //只能调用无参构造函数
// Constructor<Teacher> constructor = aClass.getConstructor();//无参构造函数对象
// Teacher teacher = constructor.newInstance();
// System.out.println(teacher);
Constructor<Teacher> constructor2 = aClass.getConstructor(int.class);//获取参数类型为String类型的一参构造函数对象
Teacher teacher = constructor2.newInstance(15);
System.out.println(teacher);
Constructor<Teacher> constructor = aClass.getConstructor(String.class, int.class);
Teacher t = constructor.newInstance("李四", 18);
System.out.println(t);
}
}
class Teacher{
private String name;
private int age;
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Teacher() {
System.out.println("无参");
}
public Teacher(String name) {
System.out.println("一餐");
this.name = name;
}
public Teacher(int age) {
System.out.println("一餐");
this.age = age;
}
public Teacher(String name, int age) {
System.out.println("全残");
this.name = name;
this.age = age;
}
}
八、获取注解类对象Annotation
可以获取到类上的注解对象,还可以获取属性上的注解对象,获取方法上的注解对象
public class Test07 {
public static void main(String[] args)throws Exception {
System.out.println("获取类上的注解对象");
Class<Doctor> aClass = Doctor.class;
Service annotation = aClass.getAnnotation(Service.class);
System.out.println(annotation);
System.out.println(annotation.value());
System.out.println("获取属性上的注解对象");
Field nameField = aClass.getDeclaredField("name");
JsonProperty annotation1 = nameField.getAnnotation(JsonProperty.class);
System.out.println(annotation1.value());
System.out.println(annotation1.required());
System.out.println("获取方法上的注解对象");
Method hello = aClass.getMethod("hello");
RequestMapping annotation2 = hello.getAnnotation(RequestMapping.class);
System.out.println(Arrays.toString(annotation2.value()));
}
}
@Service(value = "hello")
class Doctor{
@JsonProperty(value = "n",required = true)//value required都是注解的属性
private String name;
@RequestMapping(value = {"hello2","hahaha","hehe"})
public void hello(){
System.out.println("hello");
}
}
总结:
反射:运行时类中成员抽取为其他类的过程。
反射类:Class获取反射类的方式?
1.通过全类名字符串来获取。Class.forName();
2.类名来获取 类名.class
3.对象名来获取 对象名.getClass();
获取属性成员变量Field set(Object,value) get(Object);
获取方法类对象Method invoke(Object,args);
获取构造方法类对象 Constructor
获取注解类对象getAnnotation();