通过反射机制可以操作 .class 字节码文件
反射机制,让代码具有通用性,可变化的内容都是写到配置文件当中
将来只需要修改配置文件,创建的对象不一样,调用的方法也不一样
但是java代码不需要做任何的改动
java.lang.Class:代表字节码文件
java.lang.reflect.*;
java.lang.reflect.Method : 代表字节码中方法的字节码
java.lang.reflect.Constructor:代表构造方法的字节码
java.lang.reflect.Field:代表属性字节码
public class ReflectTest01 {
public static void main(String[] args) throws Exception {
// Class.forName()
//1. 静态方法
//2. 方法的参数是一个字符串,字符串需要的是一个完整类名
Class c1 = Class.forName("java.lang.String");
Class c2 = Class.forName("java.util.Date");
//Object中的方法: getClass()
String s = "abc";
Class x = s.getClass();
System.out.println(c1 == x);
// 第三种方式:静态属性
Class z = String.class;
Class k = Date.class;
//重要方法:public T newInstance()
//功能:这个方法对应类的无参数构造方法,完成对象的创建
Object obj = c1.newInstance();
System.out.println(obj);
}
}
public class ReflectTest04 {
public static void main(String[] args) {
try{
//执行的时候,类会被加载到方法区中,而类加载时静态代码块会执行
//通过这种方式,可以只让静态代码块执行
Class.forName("Reflect.User");
} catch (ClassNotFoundException e){
e.printStackTrace();
}
}
}
class User{
static {
System.out.println("静态代码块执行");
}
}
相对路径:不同编译器的相对路径不同
绝对路径:不同电脑可能存放的也不同,不同的系统的绝对路径也不同
public class AboutPath {
public static void main(String[] args) {
// Thread.currentThread()当前线程对象
// getContextClassLoader() 是线程对象的方法,可以获取到当前对象的类加载器
// getResource() 类加载器对象的方法,当前线程的类加载器默认从类的根路径下加载资源
//获取一个文件的绝对目录,该文件必须放在类路径下
String path = Thread.currentThread().getContextClassLoader()
.getResource("Reflect//CreatObject//properties").getPath();
System.out.println(path); //path是该文件的绝对路径
//直接以一个输入流的形式返回
InputStream in = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("Reflect/CreatObject/properties")
}
}
//Reflect/CreatObject/properties文件
className=Reflect.ReflectTest01
public class CreateObj {
public static void main(String[] args) throws Exception {
//升级:以前直接写路径的方式都需要修改成这样的方式获取路径,提高程序的可移植性
// String path = Thread.currentThread().getContextClassLoader().getResource("Reflect//CreatObject//properties").getPath();
// FileReader fr = new FileReader(path);
InputStream fr = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("Reflect//CreatObject//properties");
//创建属性类对象Map
Properties pro = new Properties();
//加载
pro.load(fr);
//关闭流
fr.close();
//通过key获取value
String className = pro.getProperty("className");
//通过反射机制实例化对象
Class c = Class.forName(className);
Object obj = c.newInstance();
System.out.println(obj);
}
}
//Reflect/classinfo.properties配置文件
className=Reflect.ReflectTest01
import java.util.ResourceBundle;
public class ResourceBundleTest {
public static void main(String[] args) throws Exception {
ResourceBundle bundle = ResourceBundle.getBundle("Reflect//classinfo");
String className = bundle.getString("className");
Class c = Class.forName(className);
Object obj = c.newInstance();
System.out.println(obj);
}
}
package Reflect;
public class Student {
private String name;
int age;
protected double grade;
public String id;
public static final double PI = 3.1015;
public Student() {
}
public Student(String name, int age, double grade, String id) {
this.name = name;
this.age = age;
this.grade = grade;
this.id = id;
}
public void show(){
System.out.println("无参数show方法执行");
}
public void show(int x,String s){
System.out.println("有参数show方法执行");
}
@Override
public String toString() {
return "Student{" +
"name=‘" + name + ‘\‘‘ +
", age=" + age +
", grade=" + grade +
", id=‘" + id + ‘\‘‘ +
‘}‘;
}
}
public class ReflectTest05 {
public static void main(String[] args) throws ClassNotFoundException {
//获取整个类(完整类名)
Class c = Class.forName("Reflect.Student");
String name = c.getName(); //获取完整类名
String simpleName = c.getSimpleName();
//获取类中所有的public修饰的Field(属性)
Field[] fields = c.getFields();
System.out.println(fields.length); //1
System.out.println(fields[0]); //public java.lang.String Student.id
//=======================================
Field[] fs = c.getDeclaredFields();
for(Field f : fs){
Class t = f.getType();
System.out.print(t.getSimpleName() + " ");
System.out.print(f.getModifiers() + " ");
System.out.print(Modifier.toString(f.getModifiers()) + " ");
System.out.println(f.getName());
}
}
}
public class ReflectTest06 {
public static void main(String[] args) throws ClassNotFoundException {
//拼接字符串
StringBuilder s = new StringBuilder();
Class c = Class.forName("Reflect.Student");
s.append(Modifier.toString(c.getModifiers())
+ " class " + c.getSimpleName() + " {\n");
Field[] fs = c.getDeclaredFields();
for(Field f : fs){
s.append("\t");
//获取权限
s.append(Modifier.toString(f.getModifiers()));
s.append(" ");
//获取类型
s.append(f.getType().getSimpleName());
s.append(" ");
//获取名字
s.append(f.getName());
s.append(";\n");
}
s.append("}");
System.out.println(s);
}
}
public class ReflectTest07 {
public static void main(String[] args) throws Exception{
Class c = Class.forName("Reflect.Student");
Object obj = c.newInstance();
//获取属性 -根据名称
Field f = c.getDeclaredField("name");
//打破封装,
f.setAccessible(true);
//对象:obj 属性:f 值:"zhangsan"
f.set(obj,"zhangsan");
System.out.println(f.get(obj));
}
}
语法:类型... args
public class ArgsTest {
public static void main(String[] args) {
m(2,"ad","ap");
String[] s = new String[]{"aa","bb","cc"};
m(3,s);
}
public static void m(int a, String...args){
for (int i = 0; i < args.length; i++) {
System.out.println(args[i]);
}
}
}
public class ReflectTest08 {
public static void main(String[] args) throws Exception {
Class c = Class.forName("Reflect.Student");
Object obj = c.newInstance();
//方法名:show
Method m = c.getDeclaredMethod("show",int.class, String.class);
//方法:m 对象:obj 实参:args... 返回值:retValue
Object retValue = m.invoke(obj,12,"34");
System.out.println(retValue);
}
}
public class ReflectTest09 {
public static void main(String[] args) throws Exception {
Class c = Class.forName("Reflect.Student");
//调用无参数构造方法(要保证无参数构造方法存在)
Object obj1 = c.newInstance();
//调用无参数构造方法
//第一步:获取此有参数构造方法
Constructor con = c.getDeclaredConstructor(String.class, int.class, double.class, String.class);
//第二步:调用构造方法new对象
Object obj2 = con.newInstance("zhangsan",12,34,"1111");
System.out.println(obj2);
}
}
public class ReflectTest10 {
public static void main(String[] args) throws ClassNotFoundException {
Class c = Class.forName("java.lang.String");
//获取String的父类
Class superClass = c.getSuperclass();
System.out.println(superClass.getName());
//获取String类实现的接口
Class[] is = c.getInterfaces();
for(Class i : is){
System.out.println(i.getName());
}
}
}
原文:https://www.cnblogs.com/zy200128/p/13048634.html