什么是反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
类类
所有狗 狗类 Dog 狗对象 旺财
所有猫 猫类 Cat 猫对象 肥波
所有类 类类 java.lang.Class 类对象 特定类
java.lang.Class
java.lang.reflect.Method
java.lang.reflect.Field
java.lang.reflect.construct
类属性 java.lang.reflect.Field
类方法 java.lang.reflect.Method
一切反射相关的代码都从获得java.lang.Class类对象开始
- Class.forName(完整类名)
- 类名.class
- 对象.getClass()
Student类
package com.xhh.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());
}
}
1.Class.forName(“全路径名”)
package com.xhh.reflect;
/**
* 获取类对象的方式 通过Java提供的反射机制获取到com.xhh.reflect.Student.class
* 1、Class.forName("全路径名"); jdbc/自定义mvc框架要用
* 2、类名.class 结合泛型做通用分页查询方法会用
* 3、类java.lang.Class实例(Student.class)的类实例(xhh)的getClass()获取 通用的增删改结合泛型使用
*
* @author linyaodong
*
*/
public class Demo1 {
public static void main(String[] args) throws Exception {
// 1、Class.forName("全路径名"); jdbc/自定义mvc框架要用
Class stuClz= Class.forName("com.xhh.reflect.Student");
}
}
运行结果:

2.类名.class 输出的Student完整的类名
package com.xhh.reflect;
/**
* 获取类对象的方式 通过Java提供的反射机制获取到com.xhh.reflect.Student.class
* 1、Class.forName("全路径名"); jdbc/自定义mvc框架要用
* 2、类名.class 结合泛型做通用分页查询方法会用
* 3、类java.lang.Class实例(Student.class)的类实例(xhh)的getClass()获取 通用的增删改结合泛型使用
*
* @author linyaodong
*
*/
public class Demo1 {
public static void main(String[] args) throws Exception {
// 2、类名.class 结合泛型做通用分页查询方法会用
Class stuClz1= Student.class;
System.out.println(stuClz1);
}
}
运行结果:

3.类(Class类的类对象)实例.getClass()
package com.xhh.reflect;
/**
* 获取类对象的方式 通过Java提供的反射机制获取到com.xhh.reflect.Student.class
* 1、Class.forName("全路径名"); jdbc/自定义mvc框架要用
* 2、类名.class 结合泛型做通用分页查询方法会用
* 3、类java.lang.Class实例(Student.class)的类实例(xhh)的getClass()获取 通用的增删改结合泛型使用
*
* @author linyaodong
*
*/
public class Demo1 {
public static void main(String[] args) throws Exception {
// 3、类java.lang.Class实例(Student.class)的类实例(xhh)的getClass()获取 通用的增删改结合泛型使用
Student stu=new Student();
Class stuClz2=stu.getClass();
System.out.println(stuClz2);
}
}
运行结果:

注意:ClassNotFoundException(类名错|少jar包)
注意:同一类的、类对象只会创建一个
反射三大作用
1.实例化对象
反射两大有点:
1、能够对未知的对象进行实例化
2、能够对私有构造器实例化对象
注:一定要提供无参构造器
package com.xhh.reflect;
import java.lang.reflect.Constructor;
/**
* 利用反射进行对象的实例化 之前:通过new关键字进行实例化 现在: 通过java.lang.reflect.construct来实例化对象
* 优势:
* 1、能够对未知的对象进行实例化
* 2、能够对私有构造器实例化对象
*
* @author linyaodong
*
*/
public class Demo2 {
public static void main(String[] args) throws Exception, IllegalAccessException {
// Student stu=new Student();
// Class stuClz = stu.getClass();
Class<Student> stuClz=Student.class;
// newInstance这个方法默认使用无参构造器去实例化对象
Student stu1 = (Student) stuClz.newInstance();
// System.out.println(stu1);
// 调用有参构造器去实例化对象
Constructor<Student> constructor1 = stuClz.getConstructor(String.class);
Student stu2 = (Student) constructor1.newInstance("xhh");
// 调用有参构造器去实例化对象
Constructor<Student> constructor2 = stuClz.getConstructor(String.class,String.class);
Student stu3 = (Student) constructor2.newInstance("001","xhh");
// 调用有参构造器去实例化对象
// java.lang.NoSuchMethodException
Constructor<Student> constructor3 = stuClz.getDeclaredConstructor(Integer.class);
constructor3.setAccessible(true);
Student stu4 = (Student) constructor3.newInstance(18);
}
}
运行结果:

注意:如果用getConstructor去调用私有的构造器会报错

私有的构造器如果不获取权限的话,在进行实例化时也会报错

获取权限:constructor.setAccessible(true);
2.动态调用方法
Method m;
m.invoke
2.1 无参的方法
package com.xhh.reflect;
import java.lang.reflect.Method;
/**
* 动态方法调用
* 构造方法是不是方法?
*
* @author linyaodong
*
*/
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);
}
}
运行结果:

2.2有参的方法
package com.xhh.reflect;
import java.lang.reflect.Method;
/**
* 动态方法调用
* 构造方法是不是方法?
*
* @author linyaodong
*
*/
public class Demo3 {
public static void main(String[] args) throws Exception, SecurityException {
Student stu = new Student();
Class<? extends Student> stuClz = stu.getClass();
// 有参的方法
Method m1 = stuClz.getDeclaredMethod("hello",String.class);
m1.invoke(stu,"xhh");
运行结果:

2.3私有的方法
package com.xhh.reflect;
import java.lang.reflect.Method;
/**
* 动态方法调用
* 构造方法是不是方法?
*
* @author linyaodong
*
*/
public class Demo3 {
public static void main(String[] args) throws Exception, SecurityException {
Student stu = new Student();
Class<? extends Student> stuClz = stu.getClass();
// 私有的方法
Method m2 = stuClz.getDeclaredMethod("add", Integer.class, Integer.class);
m2.setAccessible(true);
Object invoke = m2.invoke(stu, 20, 5);
System.out.println(invoke);
}
}
运行结果:

私有的方法也需要权限,如果没用也会报错

3.读写属性
Field set/get
package com.xhh.reflect;
import java.lang.reflect.Field;
/**
* 反射读写属性 自定义标签库、通用分页、自定义mvc也要用
*
* @author linyaodong
*
*/
public class Demo4 {
public static void main(String[] args) throws Exception {
Student stu = new Student("001", "xhh");
stu.age = 18;
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[] fields = stuClz.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
System.out.println("属性名:"+field.getName() + "----" +"值"+field.get(stu));
}
}
}
运行结果:

4.访问修饰符
getModifiers()
访问修饰符 getModifiers()
调用 getModifiers() 方法返回的值来对应一下的修饰符
java:
private 1
protected 2
public 4
static 8
final
abstract…
怎么判定属性或方法被那些修饰符所修饰呢?
getModifiers
3 private protected
5
本文介绍了Java反射机制,即在运行状态下可动态获取类信息和调用对象方法。从获取Class类对象开始,阐述了反射的三大作用,包括实例化对象、动态调用方法、读写属性,还提及访问修饰符的判定,同时指出使用中需注意的异常和权限问题。
1万+

被折叠的 条评论
为什么被折叠?



