栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java反射机制

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java反射机制

字节码文件对象的创建
字节码文件就是经过编译器预处理过的一种文件,是JAVA的执行文件存在形式,它本身是二进制文件,但是不可以被系统直接执行,而是需要虚拟机解释执行,由于被预处理过,所以比一般的解释代码要快,但是仍然会比系统直接执行的慢。
方式一:对象名.getClass()创建

Test test = new Test();
//方式一
Class c1 = test.getClass();
System.out.println(c1);

方式二 类名.class获取字节码文件对象

Class c2 = Test.class;
System.out.println(c2);

方式三 Class.forName("");

Class c3 = Class.forName("www.test.Test");
System.out.println(c3);

通过反射获取构造方法并使用
getConstructors()获取所有公开的构造方法。
getConstructor(类型.class…)获取指定参数类型的公开的构造方法。
getDeclaredAnnotations()获取所有的构造方法。
getDeclaredAnnotation(类型.class…)获取指定参数类型构造方法。包含private修饰的。
setAccessible(true)设置true取消java语言访问检查。

通过构造方法来实例化对象

package www.test;

import www.pojo.Person;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Test {
    public Test(){

    }
    private Test(String str){
        System.out.println("实列化....."+str);
    }
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        
//        Test test = new Test();
//        //方式一
//        Class c1 = test.getClass();
//        System.out.println(c1);
//        //方式二 类名.class获取字节码文件对象
//        Class c2 = Test.class;
//        System.out.println(c2);
        //方式三 Class.forName("");
        Class c3 = Class.forName("www.test.Test"); //获取字节码文件对象
        System.out.println(c3);
        Constructor[] constructors =c3.getConstructors(); //获取所有公开的构造方法
        for(Constructor c:constructors){
            System.out.println(c);
        }
        Constructor constructor = c3.getConstructor(null); //获取指定类型的构造方法,null为无参
        Object o = constructor.newInstance(null);
        System.out.println(o);
        Constructor declaredConstructor = c3.getDeclaredConstructor(String.class);//获取指定类型的构造方法
        declaredConstructor.setAccessible(true);
        Object o1 = declaredConstructor.newInstance("yyyy");
        System.out.println(o1);
    }
}

获取成员变量
getFields()获取所有public成员变量。
getField()获取指定的成员变量。
getDeclaredField()获取指定的成员变量(保护private修饰的)。
getDeclaredFields()获取所有的成员变量。

package www.test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

public class Test {
    private Integer id;
    private String name;
    public  String address;
    public Test(){

    }
    private Test(Integer id, String name){
        this.id=id;
        this.name=name;
    }
    public Test(Integer id, String name, String address) {
        this.id = id;
        this.name = name;
        this.address = address;
    }

    public static void main(String[] args) throws Exception{
        //1,获取字节码文件对象
        Class c = Class.forName("www.test.Test"); //获取字节码文件对象
        //2,获取构造方法
        Constructor declaredConstructor = c.getDeclaredConstructor(Integer.class, String.class);
        //3,取消访问限制
        declaredConstructor.setAccessible(true);
        //4,执行构造方法创建对象
        Object obj = declaredConstructor.newInstance(6, "张三");
        //5,获取成员变量
        Field f1 = c.getField("address");
        //6,给address属性赋值
        f1.set(obj,"成都");
        //7,取出address的值
        System.out.println("address:"+f1.get(obj));
        //8,获取私有属性name和age的值
        Field name = c.getDeclaredField("name");
        name.setAccessible(true);//解除访问限制
        System.out.println("name:"+name.get(obj));
        Field id = c.getDeclaredField("id");
        id.setAccessible(true);//解除访问限制
        System.out.println("id:"+id.get(obj));

    }
}

获取方法
在反射机制中,把类的成员方法使用类Method表示。

package www.test;
import java.lang.reflect.Method;

public class Test {
    private Integer id;
    private String name;
    public  String address;
    public Test(){

    }
    private Test(Integer id, String name){
        this.id=id;
        this.name=name;
    }
    public Test(Integer id, String name, String address) {
        this.id = id;
        this.name = name;
        this.address = address;
    }
    public void method1(){
        System.out.println("method1");
    }
    public void method2(String message){
        System.out.println(message);
    }
    public void method3(){
        System.out.println("method3");
    }

    public static void main(String[] args) throws Exception{
        //获取字节码文件对象
        Class c = Class.forName("www.test.Test"); //获取字节码文件对象
        //获取所有public修饰的方法
        Method[] methods = c.getMethods();
        for(Method m:methods)System.out.println(m);
        //获取所有的方法,保护private修饰的方法
        Method[] declaredMethods = c.getDeclaredMethods();
        //获取指定的方法
        Method method1 = c.getMethod("method1", null);//没有参数
        System.out.println(method1);
        Method method2 = c.getMethod("method2", String.class);//有一个参数
        System.out.println(method2);

    }
}

执行方法
invoke(对象,参数)执行方法

package www.test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class Test {

    public Test(){

    }

    public void method1(){
        System.out.println("method1");
    }
    public void method2(String message){
        System.out.println(message);
    }
    private void method3(){
        System.out.println("method3");
    }

    public static void main(String[] args) throws Exception{
        //获取字节码文件对象
        Class c = Class.forName("www.test.Test");
        //获取空参构造方法
        Constructor constructor = c.getConstructor(null);
        //创建对象
        Object obj = constructor.newInstance();
        //获取方法
        Method method1 = c.getMethod("method1", null);
        //执行方法
        method1.invoke(obj,null);//该方法没有参数

        Method method2 = c.getMethod("method2", String.class);
        method2.invoke(obj,"我是有参数的方法");

        Method method3 = c.getDeclaredMethod("method3", null);
        method3.setAccessible(true);
        method3.invoke(obj,null);

    }
}

泛型擦除

package www.test;

import java.lang.reflect.Method;
import java.util.ArrayList;

public class Test {
    public static void main(String[] args) throws Exception {
        //创建一个集合对象,往里添加字符串
        ArrayList list = new ArrayList<>();
        list.add(3);
        list.add(5);
        //list.add("往ArrayList里添加数据");
        Class c = Class.forName("java.util.ArrayList");
        Method add = c.getMethod("add",Object.class);//字节码是没有泛型约束的
        add.invoke(list,"hello");
        System.out.println(list);
    }
}

反射配置文件
通过反射配置文件,运行配置文件中指定类型的对应方法。
读取***.txt文件中的数据,通过反射技术,来完成pojo对象的创建。
准备txt文件

package www.test;

import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Properties;

public class Test3 {
    public static void main(String[] args) throws IOException, Exception {
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\people.txt"));
        String className = properties.getProperty("className");
        String methodName = properties.getProperty("methodName");

        Class c = Class.forName(className);
        Constructor constructor = c.getConstructor(null);
        Object obj = constructor.newInstance(null);//空参数构造方法
        Method method = c.getMethod(methodName, null);//方法没有参数
        method.invoke(obj,null);//执行方法


    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/755382.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号