0x00前言和思维导图
1.反射机制定义:java反射机制是指在java代码执行过程中,对于任意一个类,可以获取这个类的属性与方法;对于任意一个对象,可以获取、修改这个对象的属性值,调用对象的方法。这种动态获取信息和调用方法的技术就是java中的反射机制。
2.首先需要了解Class类(全限定名称是java.lang.Class)和class对象。class对象就是由Class类创建的对象,只是这个创建过程不是由用户主动创建的,而是由JVM自动实现的。JVM会为项目中每一个类(不论是JDK自带的类、第三方jar包的类、还是自己编写的类)创建一个class对象,用来保存与这个类相关的信息。class对象只与类有关,与对象无关。
0x01获取字节码文件
方法一:Class.forName(\" \"),中间需要一个String类型的classname;
Class c3=Class.forName(\"java.util.Date\");
(它的执行胡导致类的加载会导致静态模块的代码执行)
方法二:每个对象都有一个继承与Object的方法叫做getClass;返回的是一个Class
public final native Class<?> getClass();
方法三:java每一种数据类型都用有一个属性叫做class属性
Class Z=String.class;
class My_Reflect_one{
public static void main(String[] args) {
Class c1=null;
try {
c1 = Class.forName(\"java.lang.String\");
Class c3=Class.forName(\"java.util.Date\");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String s=\"abc\";
Class X=s.getClass();
System.out.println(c1==X);//返回值是True,字节码文件装载到JVM的时候只会装载一份
Class Z=String.class;
Class y=Integer.class;
}
}}
0x02获取Field(获取属性)
1.先定义一个类
class ReflectTest{
public int no=0;
private String name;
protected int age;
boolean flag;
}
2.getFields()
获取所有是public修饰的属性
public static void main(String[] args) throws Exception{
Class Test_Class=Class.forName(\"zhonglin.www.ReflectTest\");
Field[] fields= Test_Class.getFields();}
3.getDeclaredFields()
获取所有属性暴力破解,不管修饰符
public static void main(String[] args) throws Exception{
Class Test_Class=Class.forName(\"zhonglin.www.ReflectTest\");
Field[] fs= Test_Class.getDeclaredFields();//暴力获取所有属性
System.out.println(fs.length);//4个长度}
4.getTyp()
获取数据类型
(1)看下构造函数,返回值是一个Class
public Class<?> getType() {
return type;
}
public static void main(String[] args) throws Exception{
Class Test_Class=Class.forName(\"zhonglin.www.ReflectTest\");
Field[] fs= Test_Class.getDeclaredFields();//暴力获取所有属性
System.out.println(fs.length);//4个长度
for (Field field :fs){
Class filedtype=field.getType();//接受返回的Class
String fName=filedtype.getName();//调用getname方法
System.out.println(fName);
System.out.println(field.getName());
}}
5、getModifiers()和Modifier.toString()
去找到属性的修饰符
(1)构造函数 public int getModifiers()
它的返回值是一个intpublic static String toString(int mod)
它可以把对应的int输出成对应的修饰符
public static void main(String[] args) throws Exception{
Class Test_Class=Class.forName(\"zhonglin.www.ReflectTest\");
Field[] fs= Test_Class.getDeclaredFields();//暴力获取所有属性
System.out.println(fs.length);//4个长度
for (Field field:fs){
int i=field.getModifiers();
String modifiter =Modifier.toString(i);
System.out.println(modifiter);
}}
6.通过get和set方法访问和修改属性
(1)通过newInstance()方法构造出一个对象
(2)通过getDeclaredField(name)获取一个属性的值赋值给一个Field对象,可以同Filed对象.get/set
(3)get和set的构造方法
a.set():public void set(Object obj, Object value)
b.get(): public Object get(Object obj)
class Reflect_four{
public static void main(String[] args) throws Exception {
Class Test_class=Class.forName(\"zhonglin.www.ReflectTest\");
//操作对象属性
Object obj= Test_class.newInstance();
Field nofiled=Test_class.getDeclaredField(\"no\");
nofiled.set(obj,2222);
System.out.println(nofiled.get(obj));
//访问私有属性
Field namefield=Test_class.getDeclaredField(\"name\");
namefield.setAccessible(true);//打破封装
namefield.set(obj,\"jsckson\");
System.out.println(namefield.get(obj));
}
}
7.反编译文件(拓展)
综合使用学习到的方法
class Myreflect_Three{//构造好框架
public static void main(String[] args) throws Exception {
StringBuilder stringBuilder=new StringBuilder();
Class Test_class=Class.forName(\"zhonglin.www.ReflectTest\");
stringBuilder.append(Modifier.toString(Test_class.getModifiers())+\"class \"+Test_class.getSimpleName()+\"{\");
Field[] fields=Test_class.getDeclaredFields();
stringBuilder.append(\"\\n\");
for (Field field:fields)
{
stringBuilder.append(\"\\t\");
stringBuilder.append(Modifier.toString(field.getModifiers()));//获取属性的修饰符
stringBuilder.append(\" \");
stringBuilder.append(field.getType().getSimpleName());//获取属性类型
stringBuilder.append(\" \");
stringBuilder.append(field.getName());//获取属性的名字
stringBuilder.append(\";\\n\");
}
stringBuilder.append(\"}\");
System.out.println(stringBuilder);
}
}
0x02反射Method
1.基础方法和反射属性差不多。
2.方法的使用
***getDeclaredMethod(\"方法名\",...args(参数))获取方法
getReturnType()获取返回值类型
Modifier.toString((method1.getModifiers())获取修饰符
public Object invoke(Object obj, Object... args)调用方法***
3.看一下完整代码
class Reflect_five{
public static void main(String[] args) throws Exception {
Class Test_class=Class.forName(\"zhonglin.www.ReflectTest2\");
Method[] method = Test_class.getDeclaredMethods();//获取全部方法
for (Method method1:method){
System.out.println(method1.getName());
//获取返回值类型1
System.out.println(method1.getReturnType());
//获取方法的修饰符
System.out.println(Modifier.toString((method1.getModifiers())));
//获取参数列表
Class[] classes=method1.getParameterTypes();
for (Class parmeterType:classes){
System.out.println(parmeterType.getSimpleName());
}
}
}
}
class Reflect_six{
public static void main(String[] args) throws Exception{
Class Test_class=Class.forName(\"zhonglin.www.ReflectTest2\");
Object obj=Test_class.newInstance();
Method LONIN=Test_class.getDeclaredMethod(\"longin\", String.class, String.class);
Object result=LONIN.invoke(obj,\"root\",\"root\");
}
}
0x03反射Constructor
1.基础方法一致:
getModifiers()随后用toString输出;//获取修饰符
getSimpleName()//获取构造方法名其实就是获取类名
getParameterTypes()//获取参数列表
public T newInstance();//创建一个对象,这个对象可以用一个Object去获取,创建成功及调用了构造函数
点击查看代码
class Refldct_seven{
public static void main(String[] args) throws Exception{
StringBuilder stringBuilder=new StringBuilder();
Class class_Test=Class.forName(\"zhonglin.www.ReflectTest3\");
stringBuilder.append(class_Test.getSimpleName());
stringBuilder.append(\"{\");
stringBuilder.append(\"}\");
System.out.println(stringBuilder);
Constructor[] constructors=class_Test.getDeclaredConstructors();
for (Constructor constructor:constructors){
System.out.println(constructor.getDeclaringClass().getSimpleName());
constructor.getModifiers();
constructor.getParameterTypes();
}
//创建对象
Object obj= class_Test.newInstance();
System.out.println(obj);
//有参构造方法怎么调用
Constructor constructor2=class_Test.getDeclaredConstructor(int.class,String.class,String.class);
Object obj2= constructor2.newInstance(2,\"hellow\",\"hellow\");
}
}
###0x4反射父接口和父类
1.学到这里发现其实都是一些方法的使用
getSuperclass(): public native Class getSuperclass();//获取父类
getInterfaces():public Class[] getInterfaces();//获取全部接口返回值是一个路径可用循环获得
//看下实例;
class Refldct_eight{
public static void main(String[] args) throws Exception{
Class class_Test=Class.forName(\"zhonglin.www.ReflectTest4\");
class_Test.getSuperclass().getSimpleName();
Class[] in= class_Test.getInterfaces();
for (Class IN: in) {
System.out.println(IN.getSimpleName());
}
}
}
0x05
反射机制虽然说增加了代码的复杂程度但是提高代码的灵活性,在以后的框架的学习中,配置文件的修改大部分都是利用的反射机制。和利用反射机制去做Runtime类这下面方法exec,进行命令执行,后面去学习一下
来源:https://www.cnblogs.com/0x3e-time/p/16155407.html
本站部分图文来源于网络,如有侵权请联系删除。