07 Java面试反射原理

本文详细介绍了Java反射机制的使用,包括何时需要使用反射、Class类的作用、如何创建对象、操作属性和方法,以及反射的优缺点。示例代码展示了如何通过反射越过泛型添加数据,揭示了泛型在编译后的实际效果。反射在提升程序灵活性的同时,也可能带来性能和维护上的挑战。
摘要由CSDN通过智能技术生成

一、什么情况下需要使用反射?
答:
在编译时无法知道该对象或类属于哪些类,此时就可用反射了。

二、Class 类的作用及其主要功能?
答:
类是对象的设计图,Person 类可以创建多个对象,Class 类是类的设计图也就是Person类等都是一个Class类的实例,在运行时都对应着一个 Class 对象。
Class 类提供了很多方法:
比如反射技术常用到的 Class.forName(“包.类”);这样可以获取该类的 Class 对象。通过这个 Class 对象,我们可以调用该类的方法,属性,构造方法…等

三、如何使用反射创建一个对象?
答:
一种:

public static void main(String[] args) {
            try {
                //使用Class.forName()
        Class personClass = Class.forName("com.str.strs.Person");
        Person newInstance = (Person) personClass.newInstance();
               //使用xxx.getClass()
            String s = "Person";
          Class personClass1 = s.getClass();
          Person newInstance1 = (Person) personClass1.newInstance();
            //使用xxx.class
          Class personClass2 = Person.class;
          Person newInstance2 = (Person) personClass2.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

二种:

            //使用Class.forName()
Class personClass =  Class.forName("com.str.strs.Person");
         //实体列必须有对应的构造方法
         Constructor constructor = personClass.getConstructor(String.class);
        Person newInstance = (Person) constructor.newInstance("构造方法");

//其他同上
四、如何使用反射操作属性?
答:
通过 Class 对象获得属性的方法有
1、获取 public 的属性:object.getFields()
2、获取所有的属性: object.getDeclaredFields()
3、根据属性名称获取 public 的属性信息: object.getField(“age”);
4、根据属性名称获取属性的信息:object.getDeclaredField(“name”);

    Class personClass =Class.forName("MyReflect.MyPersonText");     

System.out.println(“获取所有的公共属性.并打印**************”);
Field[] field1 = personClass.getFields();
for(Field f:field1){
System.out.println(f.getName());
}

五、如何使用反射执行方法?
答:
1、方法的操作 method.invoke(对象,参数列表)
2、获取方法 由名称和参数列表类决定
3、getMethod(name, parameterTypes) 获取的public的方法
4、getDeclaredMethod(name, parameterTypes) 获取自己声明的方法

//有参数的构造方法
          Class A1 =MyPersonText.class;
          try {
            Method mt =A1.getMethod("tell", String.class);
            Constructor con = A1.getConstructor(null);
            MyPersonText  we =(MyPersonText)con.newInstance(null);
                mt.invoke(we, "自行车");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
/**
 普通的方法
*/
Students students = new Students();
       Class stClass = students.getClass();
    try {
       //这两种方法都可使用
        System.out.println("----------一种---------------");
       Method method = stClass.getMethod("start",new Class[]{int.class,int.class});
        //如有返回就返回的对应的返回值,没有则为null
        Object invoke = method.invoke(students, new Object[]{1,2});
       System.out.println(invoke);
        System.out.println("----------二种---------------");
       Method method1 = stClass.getMethod("start",String.class,String.class);
        Object invoke2 = method1.invoke(students, "小张","小组");
        System.out.println(invoke2);
   } catch (Exception e) {
      // TODO Auto-generated catch block
       e.printStackTrace();
   }

六、如何使用反射操作方法名?
答:
1、getMethods()方法是获取所有Public 修饰的方法,包括父类的
2、getDeclaredMethods()获取的是所有本类声明的方法,不包括父类的

Class stClass = String.class;
        Method[] methods = stClass.getMethods();
      for (int i = 0; i < methods.length; i++) {
            // 获取方法的返回值类型的类类型
           Class returnType = methods[i].getReturnType();
           System.out.print(returnType.getName() + " ");
           // 获取方法的名称
           System.out.print(methods[i].getName() + "(");
            // 获取参数的类型-->参数列表的类型的类类型
           Class[] parameterTypes = methods[i].getParameterTypes();
           for (Class class1 : parameterTypes) {
                System.out.print(class1.getName() + " ");
            }
           System.out.print(")");
            System.out.println();
       }

七、反射的优缺点有哪些?
答:
优点
1、反射提高了 Java程序的灵活性和扩展性,降低耦合性,提高自适应能力。它允许程序创建和控制任何类的对象,无需提前硬编码目标类。
2、许多流行的开源框架例如Struts、Hibernate、Spring在实现过程中都采用了该技术。
缺点
1、性能问题:
使用反射基本上是一种解释操作,字段和方法接入时要远慢于直接代码。因此 Java 反射机制主要应用在对灵活性和扩展性要求很高的系统框架上,普通程序不建议使用。
2、使用反射会模糊程序内部逻辑:
开发人员希望在源代码中看到程序的逻辑,反射等绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂

八、【编程题】如何使用反射越过泛型进行添加数据?
答:

 ArrayList<String> array=new ArrayList<String>();
       array.add("小张");//只能输入String类型的
       ArrayList array1=new ArrayList();
        array1.add(11);
         Class ca1=array1.getClass();
        Class ca=array.getClass();
       System.out.println(ca1==ca);
        /**
         * ca1==ca为true 说明集合的泛型只是在输入的时候生效,而在编译的时候有效
         * 越过编译就无效了
        * */
       //反射进行越过泛型
        try {
           Method method = ca.getMethod("add", Object.class);
            method.invoke(array, 123);
            //array 中有字符串和数字  方式泛型是String(反射越过泛型)
            System.err.println(array);
        } catch (Exception e) {
            e.printStackTrace();
      }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值