java反射和反编译

反射机制与什么用

Java可以通过反射操作字节码文件,通过反射机制可以操作代码片段。在java.long.refect包下。

反射机制相关的类

java.lang.refect.Class
代表字节码文件
java.lang.refect.Method
代表字节码中的方法字节码
java.lang.refect.Constructor
代表字节码中的构造方法字节码
java.lang.refect.Field
代表字节码中的属性字节码
如:

public class User{//Class
	int no;//Field
	public User(){//Constructor
	}
	public int getUser(){//Method
	}
	

获取类的字节码三种方式

1 通过Class类的静态方法获取字节码
Class c1 = Class.forName("java.lang.String");//需要完整类名,带包名
//forName有异常需要处理

c代表着相应的字节码文件。

2 通过类的getClass()方法获取
String s = "abc";
Class c2 = s.getClass();

注意c1和c2指向同一个字节码文件,c1==c2,相同类型字节码在虚拟机方法区只有一份。

3 通过class属性获取

java任何类型都有class属性

Class c3 = int.class

通过反射创建对象

Class c = Class.forName(str);
Object obj = c.newInstace();
//通过无参数构造方法构造对象,如果没有无参构造就会出错。
//forName会执行类的静态代码块

如果只想执行类的静态代码块,可以用Class.forName。

获取反射类中的各种属性方法

1 获取属性的名字
Class c = Class.forName(str);
Field[] fields = c.getFields();//只能获取公开属性的方法。
Field[] fields1 = c.getDeclaredFields();//能获取所有属性
String name = fields[0].getName();
2 获取属性的类型
Class c = Class.forName(str);
Field[] fields1 = c.getDeclaredFields();//能获取所有属性
Class type = fields1[0].getType();//获取类型
String fieldname = type.getName();//获取类型名字
3 获取属性的修饰符
Class c = Class.forName(str);
Field[] fields1 = c.getDeclaredFields();//能获取所有属性
int i = fields1[0].getModifiers();//注意返回的是int
String modifier = Modifier.toString(i);//获取修饰符名字
4 获取类中的方法和方法的参数
 Method[] mm = c.getDeclaredMethods();//获取方法
 s="";
 for(Method m :mm){
            s.append(Modifier.toString(m.getModifiers())+" ");//获取方法类型
            s.append(m.getReturnType().getSimpleName()+" " );//获取方法返回值
            s.append(m.getName());//获取方法名字
            Class[] pp = m.getParameterTypes();//获取方法参数类型
            for(Class p :pp){
                s.append(p.getSimpleName());//获取方法参数类型的名字
                s.append(",");
            }
        }

通过反射反编译出类

package homework;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class FieldTest {
    public static void main(String[] args) throws Exception{
        StringBuilder s = new StringBuilder();
        Class c = Class.forName("java.lang.String");
        Constructor con = c.getDeclaredConstructor();
        Object obj = con.newInstance();
        System.out.println(obj);

        s.append(Modifier.toString(c.getModifiers())+" class "+c.getSimpleName()+"{\n");
        Field[] ff = c.getDeclaredFields();
        Method[] mm = c.getDeclaredMethods();

        for( Field f : ff){
            s.append("\t");
            s.append(Modifier.toString(f.getModifiers())+" ");
            s.append(f.getType().getSimpleName()+" ");
            s.append(f.getName());
            s.append(";\n");
        }
        for(Method m :mm){
            s.append("\t");
            s.append(Modifier.toString(m.getModifiers())+" ");
            s.append(m.getReturnType().getSimpleName()+" " );
            s.append(m.getName());
            s.append("(");
            Class[] pp = m.getParameterTypes();
            for(Class p :pp){
                s.append(p.getSimpleName());
                s.append(",");
            }
            s.deleteCharAt(s.length()-1);
            s.append("){}\n");

        }
        s.append("}");
        System.out.println(s);
        System.out.println();
        System.out.println();
    }
}

获取类路径的方法

获取类路径下类的路径的通用方法

//Thread.currentThread当前线程
//getContexClassLoader获取当前线程的类加载器对象
//getResource()获取资源,默认从类的根路径下
Thread.currentThread.getContexClassLoader.getResource(filename).getPath();

通过反射调用方法

Class user = Class.forName("User");
Object obj = user.newInstance();
Method m = user.getDeclaredMethod(String.class,int.class);//必须给出参数类型
Object retrunvalue = m.invoke("123",3);//必须给出参数

反射的作用

1 可以直接从配置文件中读取类名,进而实例化对象

在不改源代码的情况下,就可以创建任何对象,对扩展开放,对修改关闭。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值