反射
1. 什么是反射
反射java语言中的一种机制,通过这种机制可以动态的实例化对象、读写属性、调用方法
2. 一切反射相关的代码都从获得类对象开始
- Class.forName(完整类名)
- 类名.class
- 对象.getClass()
package com.lrc.reflect;
public class Student {
private String sid;
private String sname;
public Integer age;
static{
System.out.println("加载进jvm中!");
}
public Student() {
super();
System.out.println("调用无参构造方法创建了一个学生对象");
}
public Student(String sid) {
super();
this.sid = sid;
System.out.println("调用带一个参数的构造方法创建了一个学生对象");
}
public Student(String sid, String sname) {
super();
this.sid = sid;
this.sname = sname;
System.out.println("调用带二个参数的构造方法创建了一个学生对象");
}
@SuppressWarnings("unused")
private Student(Integer age) {
System.out.println("调用Student类私有的构造方法创建一个学生对象");
this.age = age;
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public void hello() {
System.out.println("你好!我是" + this.sname);
}
public void hello(String name) {
System.out.println(name + "你好!我是" + this.sname);
}
@SuppressWarnings("unused")
private Integer add(Integer a, Integer b) {
return new Integer(a.intValue() + b.intValue());
}
}
package com.lrc.reflect;
public class Demo1{
public static void main(String[] args) {
Person p=new Person(001,"qq",11);
}
}
class Person {
private int id;
private String name;
private int age;
public Person() {
super();
}
public Person(int id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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;
}
private void hello() {
System.out.println("嘿嘿");
}
}
package com.lrc.reflect;
/**
* 获取类对象的方式
* 获取Java.lang.Class的一个类实例
* 1.通过对应类(java.lang.Class)实例的类(Student.class)getClass()方法获取
* 通用增删改查的时候用到
* 2.通过Class.forName("类的全路径");JDBC的驱动加载就用到反射技术
* 3.类实例.class
*/
public class Demo2 {
public static void main(String[] args) throws ClassNotFoundException {
// Student stu=new Student();
// Class c=stu.getClass();
Class c=Class.forName("com.lrc.reflect.Student");
Class c1=Student.class;
System.out.println(c1);
}
}
代码效果显示如下
3.反射三大作用
1 实例化对象
package com.lrc.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* 利用反射进行实例化 能够获取到Student,class 如何知道通过Student.class得到Student 的一个实例 反射的好处:
* 能够将未知的类进行实例化 tomcat中的web.xml中的servlet为什么处理用户的请求? tomcat开发人员定义好了Httpservlet
* service方法来处理网络请求
* 能够对未知的对象进行实例化
* 能够随私有构造器实例化对象
*/
public class Demo3 {
public static void main(String[] args) throws Exception {
Class c = Student.class;
//newInstance默认使用无参构造去实例化对象
// 通过反射的方式调用无参构造函数来实例化对象
// Student s=(Student)c.newInstance();
// // 通过反射的方式调用带有一个参数的构造器来实例化对象
// Constructor cs = c.getConstructor(String.class);
// Student stu = (Student) cs.newInstance("s001");
// // 通过反射的方式调用带有两个参数的构造器来实例化对象
// Constructor cs = c.getConstructor(String.class, String.class);
// Student stu = (Student) cs.newInstance("s001", "s002");
// 通过反射的方式调用私有的构造器来实例化对象
//getConstructor与getDeclaredConstructor的区别
//getConstructor获取到的是public修饰的
//getDeclaredConstructor获取的是所有的构造器
Constructor cs = c.getDeclaredConstructor(Integer.class);
cs.setAccessible(true
);
Student stu = (Student) cs.newInstance(11);
}
}
代码效果显示如下
这里会有报错
还会有一个报错
2 动态调用方法
package com.lrc.reflect;
import java.lang.reflect.Method;
/**
* 动态方法调用
*
*/
public class Demo4 {
public static void main(String[] args) throws Exception {
Class c=Student.class;
//Method m=c.getDeclaredMethod("hello");
//第一个参数指的是,类的类实例的类实例
//第二个参数,指的是调用方法携带的可变参数
//Methon类invoke方法返回值就是被调用的方法的返回值
//如果被调用的方法的不具备返回值。那么返回null
//System.out.println(m.invoke(c.newInstance()));
// Method m=c.getDeclaredMethod("hello", String.class);
// m.invoke(c.newInstance(), "qqq");
Method m=c.getDeclaredMethod("add", Integer.class,Integer.class);
m.setAccessible(true);
Object invoke=m.invoke(c.newInstance(), 11,12);
System.out.println(invoke);
}
}
代码效果显示如下
3 读写属性
package com.lrc.reflect;
import java.lang.reflect.Field;
/**
* 反射读写属性
* 自定义标签,通用分页,自定义mvc
*
*/
public class Demo5 {
public static void main(String[] args) throws Exception{
Student stu=new Student("s001","qq");
stu.age=12;
System.out.println(stu.getSid());
System.out.println(stu.getSname());
Class<?extends Student> stuc=stu.getClass();
// Field f= stuc.getDeclaredField("sname");
// f.setAccessible(true);
// System.out.println(f.get(stu));
//获取当前的属性,以及属性值
Field[] ff=stuc.getDeclaredFields();
for (Field field : ff) {
field.setAccessible(true);
System.out.println(field.getName()+":"+field.get(stu));
}
}
}
4. 访问修饰符
java : peivate、 protected、 public、 static 、final 、abstract…
如何判定属性或方法被哪些修饰符所修饰?
通过方法 **getModifiers()**得知