day025反射
反射机制 运行时创建对象
- 堆栈简述
每个对象在jvm初始化后都被封装成class对象,类对象和数组被存在堆中,静态方法,成员变量都在堆中
堆中数据由虚拟机回收机制管理,无引用后变成垃圾,
栈中存放对象的引用,和基本类型变量,方法函数 main() 栈中的数据可以共享
局部变量(方法中的变量)存在栈中,随着方法消失而消失
原理通过栈内存的引用访问堆中的数据
- Reflection 反射
Class c = Class.forName("java.lang.string")
反射可以在运行时操作对象,动态机制创建对象和编译,反射获取对象慢
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @ Author :wwwzhqwww
* @ Date :Created in 16:18 2021/2/9
* @ Description://反射创建对象,调用其方法
* @ Modified By:
* @Version: $version$
*/
public class Test12 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class cl = Class.forName("User");
System.out.println("包名+类名--"+cl.getName());//User直接在src下没有外层包User
Method[] methods = cl.getMethods();//获取对象的public方法
for (Method method : methods) {
System.out.println(method+"---method");
}
Class superclass = cl.getSuperclass();
System.out.println(superclass+"---supclass");
Field[] fields = cl.getFields();//找到public属性
for (Field field : fields) {
System.out.println("field--public--"+field);
}
Field [] fields1 = cl.getDeclaredFields();//找到所有属性包括私有属性 private
for (Field field : fields1) {
System.out.println("field--all--"+field);
}
User user = (User)cl.newInstance();//class对象通过无参构造创建对象实例,
//如果没有无参构造通过有参构造创建对象
Constructor constructor = cl.getDeclaredConstructor(String.class, int.class, int.class);//获取有参构造,传入参数类型
User user2 = (User) constructor.newInstance("name0",22,8888);//传参创建对象实例
System.out.println(user2.getName());
Method setName = cl.getDeclaredMethod("setName", String.class);//获取指定的方法,需要传入参数类型
setName.invoke(user2,"cccc");//反射调用方法
System.out.println(user2.getName());
user2.setName("qunimad");//正常调用方法
System.out.println(user2.getName());
//注意:如果反射需要用私有方法private 需要关闭检测 setAccessible(true) 可以提高效率
//测试调用方法速度
//1.正常调用
User userr = new User();
Class cl1 = userr.getClass();
long startTime = System.currentTimeMillis();
for (int i = 0; i < 910000; i++) {
userr.getAge();
}
long endTime = System.currentTimeMillis();
System.out.println("正常创建对象调用方法用时:"+(endTime-startTime));
Method getAge = cl1.getDeclaredMethod("getAge");
startTime = System.currentTimeMillis();
for (int i = 0; i < 910000; i++) {
getAge.invoke(userr);
}
endTime = System.currentTimeMillis();
System.out.println("反射调用方法用时:"+(endTime-startTime));
getAge.setAccessible(true);//关闭方法检测
startTime = System.currentTimeMillis();
for (int i = 0; i < 910000; i++) {
getAge.invoke(userr);
}
endTime = System.currentTimeMillis();
System.out.println("反射调用方法关闭方法检测用时:"+(endTime-startTime));
}
}
对象
import java.lang.annotation.ElementType;
/**
* @ Author :wwwzhqwww
* @ Date :Created in 19:00 2021/2/8
* @ Description:反射
* @ Modified By:
* @Version: $version$
*/
public class Test {
public static void main(String [] args) throws ClassNotFoundException {
User user1 = new Me();User user3 = new Me();
User user2 = new Me();User user4 = new Me();//new 每个对象的实例都会记住它来自哪个class 类 对象的class类只有一个,对应.class文件
User user = new Me();
System.out.println(user.getName());
Class cm =user.getClass();//通过getclass拿到 对象的class类
Class cme = Me.class;//对象.class拿到对象的class类
System.out.println(cme.hashCode()+"****"+cm.hashCode());//通过比较不同方式获取的hashcode证明指向同一个class
Class cuser = Class.forName("User");//传入对象路径反射拿到类
Class cmesup = cme.getSuperclass();//拿到父类
System.out.println(cuser.hashCode()+"*****"+cmesup.hashCode());
System.out.println(Object.class);//类
System.out.println(Integer.class);//整数
System.out.println(int[].class);//一维数组
System.out.println(int[][].class);//二维数组
System.out.println(Comparable.class);//接口
System.out.println(void.class);//空
System.out.println(ElementType.class);//枚举
System.out.println(Class.class);//
System.out.println(Override.class);//注解
}
}
class User{
private String name;
private int age;
private int id;
public User() {
}
public User(String name, int age, int id) {
this.name = name;
this.age = age;
this.id = id;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", 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;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
class Me extends User{
public Me(){
setName("cao");
}
}
class He extends User{
public He(){
setName("hehe");
}
}