百木园-与人分享,
就是让自己快乐。

java学习之反射机制

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
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » java学习之反射机制

相关推荐

  • 暂无文章