欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

反射学习笔记

程序员文章站 2024-03-23 14:16:58
...

反射机制主要掌握的类型


以下是sun提供的反射机制中的类

java.lang.Class;
java.lang.reflect.Constructor; 构造方法
java.lang.reflect.Filed; 属性
java.lang.reflect.Method; 方法
java.lang.reflect.Modifier; 修饰符

class user{     //Class
    private String name; //Filed&Modifier
    public User(){}      //Constructor&Modifier
    public void ml(){}   //Method$Modifier
}

反射机制的作用:

1.反编译: .class -> .java
2.通过反射机制访问Java类的属性,方法,构造方法等;

获取Class的三种方法

/*第一种*/
Class c1 = null;
try {
    //c1引用保存内存地址指向堆中对象,该对象代表的是Employee整个类;
    c1 = Class.forName("Employee");
    //若sun提供的类,必须写类全名,类全名带有包名
    Class c = Class.forName("java.util.Date");
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}
/*第二种*/
//Java中每个类型都有class属性;
Class c2 = Employee.class;

/*第三种*/
//Java语言中任何一个Java对象都有getClass方法;
Class c3 = new Employee().getClass();

Io与Properties联合运用

d:/dbinfo.txt文件中写如下

username = zhangsan

利用反射获取txt文件中的值:

//创建属性对象
Properties p= new Properties();//和Map一样,只不过key和value只能储存字符串对象
FileInputStream file = new FileInputStream("d:/dbinfo.txt");
//将file中的数据加载到属性对象中
p.load(file);
//关闭流
file.close();
String t = p.getProperty("username");
System.out.println(t);
//property属性文件可以中key,value可以用"空格","冒号","等号"
//若三者都有或重复,按最左边的作分隔符片

calssInfo.properties配置文件中写如下:

//配置文件以 文件名.properties 创建
username = java.util.Date
user=Test02User

利用反射获取.properties配置文件中的值:

//创建属性对象
Properties p = new Properties();
//创建流
FileReader fr = new FileReader("src/calssInfo.properties");
//加载
p.load(fr);
//关闭流
fr.close();
//通过key获取value
String username = p.getProperty("username");
String user = p.getProperty("user");
//通过反射获取对象
Class c = Class.forName(username);
Class c1 = Class.forName(user);
//创建对象
Object o = c.newInstance();
Object o1 = c1.newInstance();

System.out.println("username==>"+username);//username==>java.util.Date
System.out.println("user==>"+user);//user==>Test02User
System.out.println("c===>"+c);//c===>class java.util.Date
System.out.println("o===>"+o);//o===>Wed Nov 27 15:37:12 GMT+08:00 2019
System.out.println("c===>"+c1);//c===>class Test02User
System.out.println("o===>"+o1);//o===>[email protected]

反编译类的所有属性

User类

public class User {
    public String namePublic;
    protected Integer sexProtected;
    private double sexPrivate;
    Boolean addressBoolean;
}

反编译

try {
    //获取整个类
    Class c = Class.forName("User");
    Field[] declaredFields = c.getDeclaredFields();
    for (Field declaredField : declaredFields) {
        System.out.print(declaredField.getModifiers()+" ");
        System.out.print(Modifier.toString(declaredField.getModifiers())+" ");
        System.out.print(declaredField.getType().getSimpleName()+" ");
        System.out.println(declaredField.getName()+" ");
    }
    System.out.println("==============================");
    StringBuffer sb = new StringBuffer();
    sb.append(Modifier.toString(c.getModifiers())+" ");
    sb.append("class ");
    sb.append(c.getSimpleName()+" ");
    sb.append(" {"+"\n");
    for (Field declaredField : declaredFields) {
        sb.append("\t");
        sb.append(Modifier.toString(declaredField.getModifiers())+" ");
        sb.append(declaredField.getType().getSimpleName()+" ");
        sb.append(declaredField.getName()+";"+"\n");
    }
    sb.append(" }");
    System.out.println(sb);
    System.out.println("============================================");
    //获取amePublic属性
    Class user = Class.forName("User");
    Field namePublic = user.getDeclaredField("sexProtected");
    //set   and   get
    Object o = user.newInstance();
    //打破封装,接触禁止访问
    namePublic.setAccessible(true);
    System.out.println(o);
    namePublic.set(o,1);
    System.out.println(namePublic.get(o));
} catch (ClassNotFoundException e) {
    e.printStackTrace();
} catch (NoSuchFieldException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
} catch (InstantiationException e) {
    e.printStackTrace();
}
"========================================================================="
//编译结果
1 public String namePublic 
4 protected Integer sexProtected 
2 private double sexPrivate 
0  Boolean addressBoolean 
==============================
public class User  {
	public String namePublic;
	protected Integer sexProtected;
	private double sexPrivate;
	 Boolean addressBoolean;
 }
============================================
User@42d3bd8b
1

反编译某个类中的所有方法

//获取类
Class c = Class.forName("java.lang.String");
//获取所有的方法
Method[] methods = c.getMethods();
//反编译
StringBuilder sb = new StringBuilder();
sb.append(Modifier.toString(c.getModifiers()) + " class ");
sb.append(c.getSimpleName() + "\n");
for (Method method : methods) {
    sb.append("\t");
    //获取修饰符
    sb.append(Modifier.toString(method.getModifiers()) + " ");
    //获取返回值类型
    sb.append(method.getReturnType().getSimpleName() + " ");
    //获取方法名
    sb.append(method.getName() + "(");
    //获取形参
    Class[] parameterTypes = method.getParameterTypes();
    for (int i = 0; i < parameterTypes.length; i++) {
        Class parameterType = parameterTypes[i];
        if (i == parameterTypes.length-1) {
            sb.append(parameterType.getSimpleName());
        } else {
            sb.append(parameterType.getSimpleName() + " ,");
        }
    }
    sb.append("){}\n");
}
sb.append("}");
System.out.println(sb);

反编译某个类中的某个方法

LoginService 类

public class LoginService {
    public void login(String username , String passworrd){
        if (username.equals("小明")&&passworrd.equals("123")){
            System.out.println("登录成功!!!");
        }else {
            System.out.println("登录失败!!!");
        }

    }
    public void loginOut(){
        System.out.println("退出成功!!!");
    }
}

反编译调用LoginService 类

/*
* 获取某个特定的方法,利用反射机制调用*/
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
    //获取类
    Class c = Class.forName("LoginService");
    //获取特定的某个方法
    //通过: 方法名+形参列表
    Method login = c.getDeclaredMethod("login", String.class, String.class);
    //创建对象
    Object o = c.newInstance();
    //调用方法
    //调用o的login方法,传递"小明", "123"参数
    login.invoke(o, "小明", "1234");
}

反编译某个类中的所有的构造方法

//获取类
Class c = Class.forName("java.lang.String");
//获取所有的构造
Constructor[] cs = c.getDeclaredConstructors();
/*for (Constructor constructor : cs) {
    //获取修饰符
    System.out.println(Modifier.toString(constructor.getModifiers()));
    //获取构造方法名
    System.out.println(c.getName());
    //构造函数的形式参数列表
    Class[] parameterTypes = constructor.getParameterTypes();
    for (Class parameterType : parameterTypes) {
        System.out.println(parameterType.getSimpleName());
    }
}*/
/*反编译*/
StringBuilder sb = new StringBuilder();
sb.append(Modifier.toString(c.getModifiers()) + " class " + c.getName() + "{\n");
//构造方法
for (Constructor constructor : cs) {
    sb.append("\t");
    sb.append(Modifier.toString(c.getModifiers()) + " ");
    sb.append(c.getSimpleName() + "{");
    //形参
    Class[] parameterTypes = constructor.getParameterTypes();
    for (int i = 0; i < parameterTypes.length; i++) {
        Class parameterType = parameterTypes[i];
        if (parameterTypes.length - 1 == i) {
            sb.append(parameterType.getSimpleName());
        } else {
            sb.append(parameterType.getSimpleName() + " ,");
        }
    }
    sb.append("}");
}

System.out.println(sb);//获取类
Class c = Class.forName("java.lang.String");
//获取所有的构造
Constructor[] cs = c.getDeclaredConstructors();
/*for (Constructor constructor : cs) {
    //获取修饰符
    System.out.println(Modifier.toString(constructor.getModifiers()));
    //获取构造方法名
    System.out.println(c.getName());
    //构造函数的形式参数列表
    Class[] parameterTypes = constructor.getParameterTypes();
    for (Class parameterType : parameterTypes) {
        System.out.println(parameterType.getSimpleName());
    }
}*/
/*反编译*/
StringBuilder sb = new StringBuilder();
sb.append(Modifier.toString(c.getModifiers()) + " class " + c.getName() + "{\n");
//构造方法
for (Constructor constructor : cs) {
    sb.append("\t");
    sb.append(Modifier.toString(c.getModifiers()) + " ");
    sb.append(c.getSimpleName() + "{");
    //形参
    Class[] parameterTypes = constructor.getParameterTypes();
    for (int i = 0; i < parameterTypes.length; i++) {
        Class parameterType = parameterTypes[i];
        if (parameterTypes.length - 1 == i) {
            sb.append(parameterType.getSimpleName());
        } else {
            sb.append(parameterType.getSimpleName() + " ,");
        }
    }
    sb.append("}");
}

System.out.println(sb);

用反射获取某个特定的构造方法,然后创建对象

public class Test06 {
    /*
    * 获取某个特定的构造方法,然后创建对象*/
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取类
        Class c = Class.forName("Customer");
        //获取特定的构造方法
        Constructor con = c.getDeclaredConstructor(String.class, int.class);
        //创建对象
        Object o = con.newInstance("小明",18);
        System.out.println(o);
    }
}

class Customer{
    String name;
    int age;
    Customer(String name,int age){
        this.name = name;
        this.age = age;
    }
    public String toString(){
        return "Customer["+name+","+age+"]";
    }
}

通过反射获取父类和父接口

/*
    * 关于类获取父类和父接口*/
    public static void main(String[] args) throws ClassNotFoundException {
        //获取类
        Class c = Class.forName("java.lang.String");
        //获取父类
        Class superclass = c.getSuperclass();
        System.out.println(superclass.getName());
        //获取父接口
        Class[] interfaces = c.getInterfaces();
        for (Class anInterface : interfaces) {
            System.out.println(anInterface.getName());
        }
    }