java学习记录16-反射
java学习记录
- 一、什么叫反射?
- 二、测试class类的创建方式有哪些
- 三、类加载内存分析 加载->链接->初始化
- 四、分析类的初始化
- 五、获得类的信息
- 六、动态的创建对象,通过反射
- 七、性能对比分析
- 八、练习ORM 反射操作注解
一、什么叫反射?
//什么叫反射
public class Demo1 {public static void main(String[] args) throws Exception{Class c1 = Class.forName("com.dwr.reflection.User");System.out.println(c1); // class com.dwr.reflection.UserClass c2 = Class.forName("com.dwr.reflection.User");
// 一个类在内存中只有一个Class对象
// 一个类被加载后,类的整个结构都会被封装在class对象中System.out.println(c1.hashCode()); //258952499System.out.println(c2.hashCode()); //258952499}
}//实体类
class User{private String name;private int age;public User() {}public User(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public int getAge() {return age;}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}
}
二、测试class类的创建方式有哪些
//测试class类的创建方式有哪些
public class Demo2 {public static void main(String[] args) throws Exception{Person person = new Student();System.out.println(person.name);// 方式一:通过对象获得Class c1 = person.getClass();System.out.println(c1);// 方式二:forname获得Class c2 = Class.forName("com.dwr.reflection.Student");System.out.println(c2);// 方式三:通过类名.class获得Class c3 = Student.class;System.out.println(c3);// 方式四:基本内置类型的包装类都有一个TYPE属性Class c4 = Integer.TYPE;System.out.println(c4);// 获得父类类型Class c5 = c1.getSuperclass();System.out.println(c5);}
}class Person{public String name;public int age;public Person() {}public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}
}class Student extends Person{public Student(){this.name = "student";}
}
class Teacher extends Person{public Teacher(){this.name = "Teacher";}
}
三、类加载内存分析 加载->链接->初始化
//类加载内存分析 加载->链接->初始化
public class Demo5 {public static void main(String[] args) {A a = new A();System.out.println(A.m);/*栈 堆 方法区(特殊的堆)(step2)java.lang.Class对象代表Demo5类<-------------(step1)Demo5类的数据1,静态变量2,静态方法3,常量池4,代码(step4初始化) Main()m=0↓(step5) Main()m=1 (step2)java.lang.Class对象代表A类<-------------(step1)A类的数据1,静态变量| |----------------------------------> 2,静态方法| | 3,常量池| | (会寻找A类的class,然后找数据) 4,代码---------------------(step3)newA() A累的对象*//*1,加载到内存,会产生一个类对应class对象2,链接,链接结束后m = 03,初始化<Clinit>(){System.out.println("A类的静态代码块初始化");m = 100;m = 1;}m=1;*/}
}class A{static {System.out.println("A类的静态代码块初始化");m = 100;}static int m = 1;public A() {System.out.println("A类的无参构造器初始化");}
}
四、分析类的初始化
//分析类的初始化
public class Demo6 {static {System.out.println("MAIN类被加载");}public static void main(String[] args) throws ClassNotFoundException {// 主动引用
// Son son = new Son(); // => MAIN类被加载 Father类被加载 Son类被加载// 反射也会产生主动调用
// Class.forName("com.dwr.reflection.Son"); // => MAIN类被加载 Father类被加载 Son类被加载// 不会产生类的引用的方法
// System.out.println(Son.fatherkey); // => MAIN类被加载 Father类被加载 1
// Son[] array = new Son[5]; // => MAIN类被加载
// System.out.println(Son.M); // => MAIN类被加载 666}
}class Father{static int fatherkey = 1;static {System.out.println("Father类被加载");}
}
class Son extends Father{static {System.out.println("Son类被加载");childkey = 1000;}static int childkey = 2;static final int M = 666;
}
五、获得类的信息
public class Demo7 {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {Class c1 = Class.forName("com.dwr.reflection.User");// 获得类的名字System.out.println(c1.getName()); //com.dwr.reflection.UserSystem.out.println(c1.getSimpleName());//User// 获得类的属性Field[] fields = c1.getFields(); // 只能找到public属性for (Field field : fields) {System.out.println(field); // 无public属性,无输出}fields = c1.getDeclaredFields(); // 能找到所有属性for (Field field : fields) {System.out.println(field);/*private java.lang.String com.dwr.reflection.User.nameprivate int com.dwr.reflection.User.age*/}// 获得指定属性的值System.out.println(c1.getDeclaredField("name"));// 获得类的方法Method[] methods = c1.getMethods(); //获得本类及其父类的全部public方法for (Method method : methods) {System.out.println("正常的" + method);}methods = c1.getDeclaredMethods(); //获得本类所有方法for (Method method : methods) {System.out.println("getDeclaredMethods" + method);}// 获得指定方法Method getName = c1.getMethod("getName", null);System.out.println(getName);// 获得指定的构造器System.out.println(c1.getConstructors());System.out.println(c1.getDeclaredConstructors());// 获取指定的构造器System.out.println(c1.getDeclaredConstructor(String.class, int.class));}
}
六、动态的创建对象,通过反射
//动态的创建对象,通过反射
public class Demo8 {public static void main(String[] args) throws Exception {// 获取class对象Class c1 = Class.forName("com.dwr.reflection.User");
// System.out.println(c1);// 构造一个对象User user =(User) c1.newInstance();
// System.out.println(user);// 通过构造器创建对象Constructor constructor = c1.getDeclaredConstructor(String.class, int.class);User user2 = (User)constructor.newInstance("新名字", 23);
// System.out.println(user2);// 通过反射调用普通方法User user3 = (User) c1.newInstance();Method setName = c1.getDeclaredMethod("setName", String.class);
// invoke : 激活的意思
// (对象,"方法的值")setName.invoke(user3,"dwr");System.out.println(user3.getName()); // dwr// 通过反射操作属性User user4 = (User) c1.newInstance();Field name = c1.getDeclaredField("name");
// private不能这么操作 需要使用setAccessible
// 不能直接操作私有属性,我们需要关闭程序的安全检查,属性或者方法 name.setAccessible(true);name.setAccessible(true);name.set(user4, "dwr2");System.out.println(user4.getName()); //dwr2}
}
七、性能对比分析
public class Demo9 {// 普通方式public static void test1(){User user = new User();long startTime = System.currentTimeMillis();for(int i = 0;i<100000000;i++){user.getName();}long endTime = System.currentTimeMillis();System.out.println("普通方式执行1亿次" + (endTime - startTime) + "ms");}// 反射调用方式public static void test2() {User user = new User();Class c1 = user.getClass();try {Method getName = c1.getDeclaredMethod("getName", null);long startTime = System.currentTimeMillis();for(int i = 0;i<100000000;i++){getName.invoke(user, null);}long endTime = System.currentTimeMillis();System.out.println("反射方式执行1亿次" + (endTime - startTime) + "ms");} catch (NoSuchMethodException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}// 反射调用 关闭检测方式public static void test3() {User user = new User();Class c1 = user.getClass();try {Method getName = c1.getDeclaredMethod("getName", null);getName.setAccessible(true);long startTime = System.currentTimeMillis();for(int i = 0;i<100000000;i++){getName.invoke(user, null);}long endTime = System.currentTimeMillis();System.out.println("反射方式并关闭检测执行1亿次" + (endTime - startTime) + "ms");} catch (NoSuchMethodException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}public static void main(String[] args) {test1();test2();test3();}
}
八、练习ORM 反射操作注解
//练习ORM 反射操作注解
public class Demo10 {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {Class c1 = Class.forName("com.dwr.reflection.Student2");
// 通过反射获得注解Annotation[] annotations = c1.getAnnotations();for (Annotation annotation : annotations) {System.out.println(annotation);}// 获得注解的value值Table table = (Table)c1.getAnnotation(Table.class);String value = table.value();System.out.println(value);// 获得类指定的注解Field name = c1.getDeclaredField("id");FieldTable annotation = name.getAnnotation(FieldTable.class);System.out.println(annotation);}
}@Table("db_student")
class Student2{@FieldTable(columnName = "db_id",type = "int", length = 10)private int id;@FieldTable(columnName = "db_age",type = "int", length = 10)private int age;@FieldTable(columnName = "db_name",type = "varchar", length = 3)private String name;Student2() {}Student2(int id, int age, String name) {this.id = id;this.age = age;this.name = name;}public int getId() {return id;}public void setId(int id) {this.id = id;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Student2{" +"id=" + id +", age=" + age +", name='" + name + '\'' +'}';}
}//类名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Table{String value();
}//属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldTable{String columnName();String type();int length();
}
java学习记录16-反射相关推荐
- java多线程阶乘_【java学习记录】11.用多线程实现阶乘的计算过程和结果的读取(thread类ReadThread )...
(源码在上传的压缩包"[java学习记录]11.多线程实现阶乘计算(Thread类和Runnable接口)"中可看到,该压缩包可下载)java * 采用Thread类的子类实现线程 ...
- java学习记录十五:集合二Collections、Set、Map
java学习记录十五:集合二 一.Collections工具类 一.解释 二.常用方法 1.打乱集合顺序 2.按照默认规则排序 3.按指定规则排序 4.批量添加元素 二.可变参数 一.解释 二.写法 ...
- Java学习记录五(多线程、网络编程、Lambda表达式和接口组成更新)
Java学习记录五(多线程.网络编程.Lambda表达式和接口组成更新) Java 25.多线程 25.1实现多线程 25.1.1进程 25.1.2线程 25.1.3多线程的实现 25.1.4设置和获 ...
- Java学习记录02
Java学习记录02 在学习中,博客的书写不可缺少,相应的markdown基本语法也要掌握,下面是自己在CSDN上查找并学习的链接:Markdown语法 2.6项目实训:基于控制台设计简易打折与累加计 ...
- java学习第16天
java学习第16天 多线程 进程和线程 进程Process 每一个程序运行就会创建一个进程. 进程是由操作系统管理 每一个进程独享一段内存空间,进程之间互不干扰. 线程Thread 线程是进程的组成 ...
- Java注解学习记录(反射也能实现ButterKnife)
文章目录 什么是注解(Annotation) 注解有什么用 注解怎么用 注解关键字 @interface 注解属性的数据类型 元注解 @Retention @Target @Documented @I ...
- Java学习记录_1:MOOC《零基础学Java语言》课后习题解
Hey,我是寒水,一名大二学生,电子商务专业在读,正在学习Java中.我试图将在Java学习中遇到的一些困惑和最终的解答发在这个账号上,希望以此来激励我不要放弃学习! 在学习记录这个专题中,我收藏一些 ...
- 我的Java学习记录
JAVA 程序 1.Java语言的特点 2.多线程 3.Java语言的跨平台 4.Java运行机制 5.JDK.JRE 6.Java程序的开发步骤 7.关键字 8.标识符 9.java的基本数据类型 ...
- Java学习记录之简单的图书管理系统(完善中)
电子书管理系统 功能划分 最核心的功能 提供图书管理的服务 添加图书 查询 检索所有的图书 按已知检索图书信息 图书的删除 图书信息的更新 用户 用户的类型 管理员:图书的添加.更新.删除操作 普通用 ...
最新文章
- List and ArrayList
- ExecutorService 的理解与使用
- wtl中显示html,用WTL构建HTML界面应用程序(1)
- java中集合的模型特点_Java 学习笔记(十四)集合
- 【赠书】五一假期福利,OpenCV4最新原理与实战书籍
- 系统上关闭是意外的_紧急关闭iOS13,有史以来跳版本关闭系统
- 点乘 线性代数_如果看了这些还不懂线性代数,你就来锤我和广坤
- stm32单片机屏幕一直闪_STM32物联网实战项目 - 项目需求
- Android基于腾讯云的小直播开发步骤
- Excel的FIND函数及其用法
- 中山纪中集训Day5叒是测试
- win7升级到win10所遇到的坑
- 修改win7的登录界面背景与关机背景
- JAVAweb开发(一)javaweb概述
- tp5分配计费统计小例
- java计算长方形面积代码小数_求一个计算正方形面积的Java程序
- 「MOSS - 16」MOSS队:Scrum Meeting 7
- python_discover方法遍历所有执行的用例
- 2.pygame安装
- 灰狼优化算法求函数最优值matlab,GWO(灰狼优化)算法MATLAB源码逐行中文注解(转载)...