一.反射机制 class
(1)dos:Java先编译(.class:字节码文件)后去运行
(2)JVM:虚拟机去运行我们的字节码文件
(3)字节码的信息:类名,方法,属性
测试前的准备工作
(1) 、我们先来创建一个User类
public class User {
private String name;
private Integer age;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public User() {
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public void say(){
System.out.println("乐乐是我最爱的宝宝"+name+""+age);
}
private void eat(){
System.out.println("我最爱的宝宝是乐乐"+name);
}
}
(2) 、我们再来通过一些方式创建一个User对象
二.传统方式创建对象
public class Demo {
public static void main(String[] args) {
//1.传统方式创建对象(使用new关键字)
//2.创建一个对象靠的是构造函数
//3.获取到类的构造函数
//4.调用构造函数,开辟地址空间,储存构造函数生成对象
User user = new User();
//Driver d = Class.forName("com.mysql.jdbc.Driver"); 反射的过程
}
}
三.通过反射方式创建对象(有三种方式)
//1.获取字节码的方式一
//Class.forName("完整类名");完整类名:要带上当前所在的包
Class class1 = Class.forName("com.gyy.pojo.User");
//2.获取字节码的方式二
//使用类.class
Class class2 = User.class;
//3.获取字节码的方式三
//使用对象.getClass();
Class clsss3 = user.getClass();
//三者的关系
//Class使用的是单例设计(singleton),hashCode也相同
System.out.println(class1==class2);//true
System.out.println(class2==class3);//true
System.out.println(class1.equals(class2));//true
注意:对于反射来说,第一种用的最多
四.创建一个Demo2类,测试反射
(1)、获取User类的字节码
public class Demo2 {
public static void main(String[] args) throws Exception {
//1.获取User类的字节码
Class userClass = Class.forName("com.gyy.pojo.User");
//2.调用getName()查看全类名 Java的API
System.out.println(userClass.getName());
}
测试结果如下:
"C:\Program Files\Java\jdk1.8.0_201\bin\java.exe" ... com.gyy.pojo.User Process finished with exit code 0
//使用字节码模拟new关键字创建对象
//3.构造对象
Object o = userClass.newInstance();//默认调用无参构造
System.out.println("构建的对象"+o);
测试结果如下:
构建的对象com.gyy.pojo.User@1b6d3586
(2)、获取属性
//4.获取属性
Field[] fields = userClass.getDeclaredFields();//获得所有申明的属性,返回值是一个数组
System.out.println(fields.length);
//获取指定属性
Field field = userClass.getDeclaredField("name");
System.out.println(field);
//获取所有public修饰的属性
Field[] fields1 = userClass.getFields();
System.out.println(fields1.length);
测试结果:
2 private java.lang.String com.gyy.pojo.User.name 0
(2)、获取私有属性
//给属性赋值 设置私有属性,私有方法--->暴力访问
field.setAccessible(true);
field.set(u,"小宝贝");
System.out.println("私有属性字段:"+field.get(u));
测试结果:
私有属性字段:小宝贝
(3)、获取构造函数
//获取构造函数getConsreuctor()
Constructor constructor = userclazz.getConstructor();
System.out.println(constructor);
//调用构造函数创建对象
User user1 = (User) constructor.newInstance();//调用无参数的构造函数
System.out.println(user1);
测试结果:
public com.gyy.pojo.User() com.gyy.pojo.User@1540e19d
结语:技术无他,唯有熟尔,知其然,也知其所以然!