反射
通过反射获取堆区中对应的字节码文件对象 Class。
1、反射介绍:
1.通过字节码文件对象,使用该对象来获取一个类的所有的信息
(成员方法 成员变量 构造方法 静态方法 常量 访问权限修饰符 泛型 …包括私有)
2.Java是面向对象语言,Java编译生成的字节码文件应该也是一个对象,而这个对象不需要我们定义,
3.Java已经事先定义好了一个类叫做Class
4.Class类是用来描述现实事物的,是Java语言的最基本单位,类作为一个概念存在,概念本身也是一个对象
而我们使用Class类来描述这个概念类
2、反射的好处: 框架的核心
1.通过反射技术可以获取到字节码文件对象,
2.使用这个字节码文件对象就可以获取到一个类的所有信息,包括私有
【构造方法对象,成员变量对象,成员方法对象,访问权限修饰符对象…】
3.使得代码的可维护和可扩展大大提高。
3、了解相关的反射的的对象和包
java.lang.reflect包
Class 类对象
Constructor 构造方法对象
Method 成员方法对象
Field 成员变量对象
Modifier 访问权限修饰符对象
反射对象:
package com.DZY.reflect;
public class Student {
private String sid;
private String sname;
public Integer age;
static{
System.out.println("加载T237-DZY!");
}
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 Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
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.获得类对象的三种方式。
代码如下:
package com.DZY.reflect;
public class Demo1 {
public static void main(String[] args) throws Exception {
//1、Class.forName("全路径名"); jdbc/自定义mvc框架要用
// Class stu= Class.forName("com.DZY.reflect.Student");//包名.类名。
//直接远行:运行结果:他会调用静态代码块。
// 2、类名.class 结合泛型做通用分页查询方法会用.
/* Class stu=Student.class;
System.out.println(stu);*/
//直接远行:获得类的全路径名。
//3、类java.lang.Class实例(Student.class)的类实例的getClass()获取 通用的增删改结合泛型使用
/* Student stu=new Student();
Class stu2=stu.getClass();
System.out.println(stu2);*/
//获得类对象的静态代码块、无参构造方法、类的全路径名。
//如果没有打印语句stu2,就不会出现类的全路径名。
}
}
- 1、Class.forName(“全路径名”); jdbc/自定义mvc框架要用
- 2、类名.class 结合泛型做通用分页查询方法会用.
- 3、类java.lang.Class实例(Student.class)的类实例的 getClass()获取 通用的增删改结合泛型使用
2、反射实例化对象
package com.DZY.reflect;
import java.lang.reflect.Constructor;
/**
* 利用反射进行对象的实例化 之前:通过new关键字进行实例化
* 现在: 通过java.lang.reflect.construct来实例化对象
* 优势:
* 1、能够对未知的对象进行实例化
* 2、能够对私有构造器实例化对象
*
* @author Aromanic150
*
*/
public class Demo2 {
public static void main(String[] args) throws Exception, IllegalAccessException {
/* Student stu=new Student();
Class stugc=stu.getClass();*/
//获得类对象的静态代码块、无参构造方法.
Class<Student> stugc=Student.class;
//newInstance这个方法默认是使用无参构造器去实例化对象
/* Student stu2=(Student)stugc.newInstance();
System.out.println(stu2);*/
//调用有参构造器去实例化对象
/* Constructor<Student> constructor = stugc.getConstructor(String.class);
Student stu2 = (Student) constructor.newInstance("kin");
System.out.println(stu2.getSid());*/
//调用方法参数,然后设置参数值
//调用有构造器去实例化对象
/* Constructor<Student> constructor = stugc.getConstructor(String.class,String.class);
Student stu2 = (Student) constructor.newInstance("1","DZY");
System.out.println(stu2.getSid());
System.out.println(stu2.getSname());*/
// 调用私有构造器去实例化对象
// java.lang.NoSuchMethodException:
// getConstructor与getDeclaredConstructor的区别(getConstructor只能获取被public修饰的构造器,getDeclaredConstructor被所有关键字修饰的构造器)
// Class com.zking.reflect.Demo2 can not access a member of class com.zking.reflect.Student with modifiers "private"
Constructor<Student> constructor = stugc.getDeclaredConstructor(Integer.class);
constructor.setAccessible(true);
Student stu2 = (Student) constructor.newInstance(18);
System.out.println(stu2.getAge());
}
}
1、第一个打印结果:
2、第二个打印结果:
3、第二个打印结果:
4、第四个打印结果:
5、第五个打印结果:
3、反射动态调用方法:
代码如下:
package com.DZY.reflect;
import java.lang.reflect.Method;
/**
* 动态方法调用
* 构造方法是不是方法?
* @author Aromanic150
*
*/
public class Demo3 {
public static void main(String[] args) throws Exception, SecurityException {
Student stu = new Student();
stu.setSname("DZY");//设置名字
Class<? extends Student> stugc = stu.getClass();
/*Method m= stugc.getDeclaredMethod("hello");
m.invoke(stu);*/
//调用Student里hello方法
/* Method m= stugc.getDeclaredMethod("hello",String.class);
m.invoke(stu,"kin");*/
//调用Student里hello方法逗号后面加参数类型
Method m= stugc.getDeclaredMethod("add",Integer.class,Integer.class);
m.setAccessible(true);//方法设置了私有化,需要给权限;
//Method.invoke的返回值是被动态调用的方法的返回值
Object invoke = m.invoke(stu,20,5);
System.out.println(invoke);
}
}
1、第一个打印结果:
2、第二个打印结果:
3、第三个打印结果:
4、反射读取属性
代码如下:
package com.DZY.reflect;
import java.lang.reflect.Field;
/**
* 反射读写属性 自定义标签库、通用分页、自定义mvc也要用
*
* 5. 访问修饰符
getModifiers()
java:
private 1
protected 2
public 4
static 8
final abstract....
怎么判定属性或方法被那些修饰符所修饰呢?
getModifiers
3 private protected
5
*
* @author Aromanic150
*
*/
public class Demo4 {
public static void main(String[] args) throws Exception, IllegalAccessException {
Student stu = new Student("1", "DZY");
stu.age = 22;
/*System.out.println(stu.getSid());
System.out.println(stu.getSname());*/
Class<? extends Student> stugc = stu.getClass();
// Field f = stugc.getDeclaredField("age");
// f.setAccessible(true);
// System.out.println(f.get(stu));
// 获取当前Student实例中的stu所有属性及其属性值
Field[] fields = stugc.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
System.out.println(field.getName() + ":" + field.get(stu));
}
}
}
1、第一个打印结果:
2、第二个打印结果:
3、第三个打印结果:
其他详细,请点击下面网站
https://blog.csdn.net/lyk1599021827/article/details/90044770#2__386