什么是反射:
反射java语言中的一种机制,通过这种机制可以动态的实例化对象、读写属性、调用方法
类:
类属性 java.lang.reflect.Field
类方法 java.lang.reflect.Method
先创建一个student实体类
package com.xiaoyi.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());
}
}
一切反射相关的代码都从获得java.lang.Class类对象开始
package com.xiaoyi.reflect;
/**
*获取类对象的方式
*通过java提供的反射机制获取到com.xiaoyi.reflect.Student.class
* 1.Class.forName("传路径名");jdbc/自定义mvc框架要用
* 2.类名.class 结合泛型做通用分页查询方法会用
* 3.类实例的类实例的getClass()获取 通用的增删改结合泛型使用
*
*/
public class Demo1 {
public static void main(String[] args) throws Exception {
//1.传路径名
//Class StuClz=Class.forName("com.xiaoyi.reflect.Student");
//2.类名.class
//Class StuClz=Student.class;
//System.out.println(StuClz);//配置地址 class com.xiaoyi.reflect.Student
//3.类实例的类实例的getClass()获取
/* Student stu=new Student();//先创建一个类
Class StuClz=stu.getClass();//用创建一个类里面的类实例来调用getClass()获取
System.out.println(StuClz);
*/
}
}
以下为效果:
1.Class.forName(“传路径名”);
2.类名.class
3.类实例的类实例的getClass()获取
反射三大作用(java.lang.reflect.*)
package com.xiaoyi.reflect;
import java.lang.reflect.Constructor;
/**
*利用反射进行对象实例化
*之前,通过new关键字进行实例化
*现在,通过java.lang.reflect.construct来实例化对象
* 去掉student的无参构造器会报错误
*
* 反射的优点:
* 1.能够对未知的对象进行实例化
* 2.能够对私有构造器实例化对象
*
* //tomact底层原理:
//new xxxServlet.service();
//研发tomcat服务器这个人,他能够知道未来的莫一天某一个程序员写了一个xxxServlet
//web.xml xxxServlet xxxServlet实例化.service
//对web.xml进行建模,拿到全路径名,Class.forName("com.xiaoyi.xxServlet").newInstance();把new xxxServlet给替代了
//继承了 HttpServlet ser=Class.forName("com.xiaoyi.xxServlet").newInstance();
//HttpServlet Servlet
//ser.service
*
*
*/
public class Demo2 {
public static void main(String[] args) throws Exception, IllegalAccessException {
//Student stu=new Student();
//Class stuClz=stu.getClass();
Class stuClz=Student.class;
//newInstance这个方法默认是使用无参构造器去实例化
//无参方法
/*Student stu2=(Student) stuClz.newInstance();
System.out.println(stu2);
*/
//反射优点:
//1.调用有参构造器实例化
/*Constructor<Student>constructor= stuClz.getConstructor(String.class,String.class);
Student stu= constructor.newInstance("s001","zs");
*/
//2.私有构造器实例化对象
//java.lang.NoSuchMethodException:没有找到匹配的方法
// getConstructor与getDeclaredConstructor的区别 :
//getConstructor只能获取被 public修饰的构造器,getDeclaredConstructor被所以关键字修饰的构造器
//没有权限不能访问private:Class com.xiaoyi.reflect.Demo2 can not access a member of class com.xiaoyi.reflect.Student with modifiers "private"
Constructor<Student>constructor= stuClz.getDeclaredConstructor(Integer.class);
constructor.setAccessible(true);
Student stu= constructor.newInstance(19);
}
}
效果如下:
1.调用了无参方法:
2.调用带二个参数的构造方法:
3.私有的构造方法:
动态方法调用
package com.xiaoyi.reflect;
import java.lang.reflect.Method;
/**
*动态方法调用
*构造方法是方法
*/
public class Demo3 {
public static void main(String[] args) throws Exception, SecurityException {
Student stu=new Student();
Class<? extends Student> stuClz=stu.getClass();
//无参调用
/* Method m=stuClz.getDeclaredMethod("hello");
m.invoke(stu);*/
//有参调用
/*Method m=stuClz.getDeclaredMethod("hello", String.class);
m.invoke(stu, "hehe");
*/
//私有调用
Method m=stuClz.getDeclaredMethod("add", Integer.class,Integer.class);
m.setAccessible(true);//需要给权限
//Method.invoke的返回值是被动态调用的方法的返回值
Object invoke=m.invoke(stu,22,9);
System.out.println(invoke);
}
}
效果如下:
1.无参调用:
2.调用有参:
3.私有调用:
反射读写属性:
package com.xiaoyi.reflect;
import java.lang.reflect.Field;
/**
*反射读写属性
*自定义标签库、通用分页、自定义mvc也要用
*
*/
public class Demo4 {
public static void main(String[] args) throws Exception, SecurityException {
Student stu=new Student(“s001”,“hehe”);
stu.age=25;
System.out.println(stu.getSid());
System.out.println(stu.getSname());
Class<? extends Student>stuClz=stu.getClass();
//Field f=stuClz.getDeclaredField(“age”);
// f.setAccessible(true);//私有的
// System.out.println(f.get(stu));
//获取当前student实例中的stu所有属性及其属性值
Field[]fileds=stuClz.getDeclaredFields();
for (Field field : fileds) {
field.setAccessible(true);
System.out.println(field.getName()+":"+field.get(stu));
}
}
}
效果如下:
访问修饰符 getModifiers();
java里面的访问修饰符:
private 1
protected 2
public 4
static 8
final abstract……
怎么判断属性或方法被那些修饰符所修饰了?
调用 getModifiers方法
3 private protected