Java——5个Demo带你学懂反射机制中最基础最重要的内容
Posted 张起灵-小哥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java——5个Demo带你学懂反射机制中最基础最重要的内容相关的知识,希望对你有一定的参考价值。
文章目录:
Demo2:如何通过反射机制访问一个Java对象的属性?(Field)
Demo3:如何通过反射机制调用一个对象的方法?(Method)
Demo4:如何通过反射机制创建一个对象?(Constructor)
Demo5:给你一个类,如何获取这个类的父类、已实现的接口?
写在前面
- 反射机制有什么用?
通过java语言中的反射机制可以操作字节码文件。
优点类似于黑客。(可以读和修改字节码文件。)
通过反射机制可以操作代码片段。(class文件。)- 反射机制的相关类在哪个包下?
java.lang.reflect.*;- 反射机制相关的重要的类有哪些?
java.lang.Class:代表整个字节码,代表一个类型,代表整个类。
java.lang.reflect.Method:代表字节码中的方法字节码。代表类中的方法。
java.lang.reflect.Constructor:代表字节码中的构造方法字节码。代表类中的构造方法
java.lang.reflect.Field:代表字节码中的属性字节码。代表类中的成员变量(静态变量+实例变量)。
//java.lang.Class:
public class User{
// Field
int no;
// Constructor
public User(){
}
public User(int no){
this.no = no;
}
// Method
public void setNo(int no){
this.no = no;
}
public int getNo(){
return no;
}
}
关于JDK中自带的类加载器
- 什么是类加载器?
专门负责加载类的命令/工具。
ClassLoader- JDK中自带了3个类加载器
启动类加载器: rt.jar
扩展类加载器: ext/*.jar
应用类加载器: classpath- 首先通过 “启动类加载器” 加载。如果通过 “启动类加载器” 加载不到的时候,会通过 "扩展类加载器" 加载。如果 “扩展类加载器” 没有加载到,那么会通过 “应用类加载器” 加载。
- java中为了保证类加载的安全,使用了双亲委派机制。
优先从启动类加载器中加载,这个称为“父”;“父”无法加载到,再从扩展类加载器中加载,这个称为“母”。双亲委派。如果都加载不到,才会考虑从应用类加载器中加载。直到加载到为止。
Demo1:获取Class的三种方式
package com.szh.reflect;
import java.util.Date;
/**
* 要操作一个类的字节码,需要先获取这个类的字节码
* 怎么获取 java.lang.Class 实例?
* Class.forName()
* 1.静态方法
* 2.方法的参数是一个字符串
* 3.字符串必须是一个完整类名的全限定名称
*/
public class ReflectTest01 {
public static void main(String[] args) {
/*
Class.forName()
1.静态方法
2.方法的参数是一个字符串
3.字符串必须是一个完整类名的全限定名称
*/
try {
//c1代表String.class文件,或者说c1代表String类型,下面c2、c3、c4同理
Class c1=Class.forName("java.lang.String");
Class c2=Class.forName("java.util.Date");
Class c3=Class.forName("java.lang.Integer");
Class c4=Class.forName("java.lang.System");
System.out.println(c4.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//Java中任何一个对象都有一个方法:getClass()
String s="abc";
//x代表String.class文件,或者说x代表String类型
Class x=s.getClass();
System.out.println(x.getName());
//Java中任何一种类型(包括基本数据类型),都有一个 class 属性
Class z=String.class;
Class i= Date.class;
Class j=int.class;
Class k=Double.class;
System.out.println(i.getName());
}
}
Demo2:如何通过反射机制访问一个Java对象的属性?(Field)
package com.szh.bean;
/**
*
*/
public class Student {
public int id;
private String name;
protected int age;
boolean sex;
}
package com.szh.reflect;
import java.lang.reflect.Field;
/**
* 必须掌握:如何通过反射机制访问一个Java对象的属性?
* 给属性赋值 set
* 获取属性的值 get
*/
public class ReflectTest07 {
public static void main(String[] args) throws Exception {
//通过反射机制获取Class,通过Class实例化对象
Class studentClass=Class.forName("com.szh.bean.Student");
//newInstance() 这个方法会调用Student类中的无参构造方法,完成对象的创建
//obj此时是一个Student对象
Object obj=studentClass.newInstance();
//获取公共属性:id
Field idField=studentClass.getDeclaredField("id");
//给obj对象的id属性赋值
idField.set(obj,1001);
//获取obj对象的id属性值
System.out.println(idField.get(obj));
//获取私有属性:name
Field nameField=studentClass.getDeclaredField("name");
//打破封装
nameField.setAccessible(true);
//给obj对象的name属性赋值
nameField.set(obj,"张起灵");
//获取obj对象的name属性值
System.out.println(nameField.get(obj));
}
}
Demo3:如何通过反射机制调用一个对象的方法?(Method)
package com.szh.bean;
/**
*
*/
public class UserService {
public boolean login(String username,String password) {
if ("root".equals(username) && "12345678".equals(password)) {
return true;
}
return false;
}
public void logout() {
System.out.println("成功退出!");
}
}
package com.szh.reflect;
import java.lang.reflect.Method;
/**
* 必须掌握:通过反射机制调用一个对象的方法
*/
public class ReflectTest08 {
public static void main(String[] args) throws Exception {
//获取类
Class userServiceClass=Class.forName("com.szh.bean.UserService");
//创建对象
Object obj=userServiceClass.newInstance();
//获取类中的Method
Method loginMethod=userServiceClass.getDeclaredMethod("login", String.class, String.class);
//调用方法
/*
loginMethod 是方法
obj 是对象
"root","12345678" 是实参
retValue 是返回值
合起来:调用UserService类中的userService对象调用login方法,传入"root","12345678"实参,获取retValue返回值
*/
Object retValue=loginMethod.invoke(obj,"root","12345678");
System.out.println(retValue);
}
}
Demo4:如何通过反射机制创建一个对象?(Constructor)
package com.szh.bean;
/**
*
*/
public class Vip {
public int no;
public String name;
public String birth;
public boolean sex;
public Vip() {
}
public Vip(int no) {
this.no = no;
}
public Vip(int no, String name) {
this.no = no;
this.name = name;
}
public Vip(int no, String name, String birth) {
this.no = no;
this.name = name;
this.birth = birth;
}
public Vip(int no, String name, String birth, boolean sex) {
this.no = no;
this.name = name;
this.birth = birth;
this.sex = sex;
}
@Override
public String toString() {
return "Vip{" +
"no=" + no +
", name='" + name + '\\'' +
", birth='" + birth + '\\'' +
", sex=" + sex +
'}';
}
}
package com.szh.reflect;
import java.lang.reflect.Constructor;
/**
* 必须掌握:通过反射机制创建一个对象
*/
public class ReflectTest09 {
public static void main(String[] args) throws Exception {
Class vipClass=Class.forName("com.szh.bean.Vip");
//调用无参构造方法
Constructor c=vipClass.getConstructor();
Object obj=c.newInstance();
System.out.println(obj);
//调用有参构造方法
//第一步:先获取这个对象的有参构造方法
Constructor constructor=vipClass.getDeclaredConstructor(int.class,String.class,String.class,boolean.class);
//第二步:调用有参构造方法new对象
Object newObj=constructor.newInstance(1001,"张起灵","2000-05-01",true);
System.out.println(newObj);
}
}
Demo5:给你一个类,如何获取这个类的父类、已实现的接口?
package com.szh.reflect;
/**
* 给你一个类,如何获取这个类的父类、已实现的接口
*/
public class ReflectTest10 {
public static void main(String[] args) throws Exception {
//String
Class stringClass=Class.forName("java.lang.String");
//获取String的父类
Class superClass=stringClass.getSuperclass();
System.out.println(superClass.getName());
//获取String类实现的所有接口
Class[] strings=stringClass.getInterfaces();
for (Class c : strings) {
System.out.println(c.getName());
}
}
}
以上是关于Java——5个Demo带你学懂反射机制中最基础最重要的内容的主要内容,如果未能解决你的问题,请参考以下文章