JAVA中的反射机制

意义

反射是java中的动态机制,它允许我们在程序运行期间再确定类的实例化,方法的调用,属性的调用等,而不是传统意义上的在编码期间确定。

因此,反射可以大大的提高代码的灵活度,但是随之而来的是更多的系统开销和较慢的运行速度,因此不能过度的依赖反射。

反射机制第一步:在程序运行期间获取要操作的类的类对象。
类对象:Class类的实例
JVM加载一个类时,就会实例化一个Class的实例与其绑定,并且这个Class实例中会记录加载的类的一切信息:
类名,包名,属性,方法,构造器。

类对象有三种获取方式

第一种:通过类名点class

package reflectt;

import java.io.File;
import java.lang.reflect.Method;


public class reflecT {
    public static void main(String[] args) throws Exception {
    

    Class cla=String.class;
    System.out.println(cla.getname());//class java.lang.String


    //注意:基本类型只有这种用着种方式来获取类对象
    Class cl=int.class;
    System.out.println(cl.getName());//int

    Class cc=reflecT.class;    
    System.out.println(cc.getName());//reflectt.reflecT

    }
}

注意:基本类型只能用这种方式来获取!

第二种:

Class.forname();

完整的类名 即:包名点类名 以此处为例:reflectt.reclecT

package reflectt;

import java.io.File;
import java.lang.reflect.Method;


public class reflecT {
    public static void main(String[] args) throws Exception {

    Class cla=Class.forname("relfectt.rflecT");

    Class c=Class.forname("java.lang.String");

第三种:

用CLass 类名点 class点getClassL=点oader.getResouse点toUri

reflecT.class.getClassLoader.getResouse.toUri

package reflect;

import java.io.File;
import java.lang.reflect.Method;


public class reflecT {
    public static void main(String[] args) throws Exception {
            

        //该文件所在目录的上一个目录下,即:上两级下的
         File cls=new File(reflecT.class.getResource(".").toURI());

        //该文件所在目录下的,即:上以及下的
        File c=new File(reflecT.class.getClassLoader().getResource(".").toURI());

        File[] files=cls.listFiles();
        for (File file : files) {
            System.out.println(file.getName());//与其项目同级的
        }
        System.out.println("----------------------------");

        File[]  ff= c.listFiles();//与本类同级的
        for (File file : ff) {
            System.out.println(file.getName());
        }

 2,获取方法

Method称为方法对象,该类的每一个实例用于表示一个方法,该对象上记录这其表示的方法里的所有信息
如:方法的访问修饰符,返回值类型,方法名,参数列表信息等。
package reflect;

import java.io.File;
import java.lang.reflect.Method;


public class reflecT {
    public static void main(String[] args) throws Exception {
        
        //获取指定的类
        Class cls = Class.forname("reflect");

        
        //或取指定类的方法 hello方法
        Method method = cls.getMethod("hello");
        
        //获取指定类的所有方法
        Method[] methods = clss.getMethods();

        //增强for循环
        for(Method m : methods){
           
        System.out.println(m.getName);//reflect类里面的所有方法名
        }






    
    }
}
            
利用反射机制实例化对象,并调用有参和无参构造器。
package reflect;

import java.io.File;
import java.lang.reflect.Method;


public class reflecT {
    public static void main(String[] args) throws Exception {
     

    Class cla = Class.forName("good");//获取类对象



    Object obj = cla.newInstance();//该方法会调用Class所表示的类的[无参构造器]实例化对象
 
    System.out.println(obj);
    //Person{name='张三', age=22}

    
   
         // Class提供的获取特定构造器的方法:
         //   Constructor  getConstructor(Class... argsType)
         //   要将特定构造器的参数类型对应的类对象有序传入即可

       Constructor cc = cla.getConstructor(String.class,int.class);//这里传入每个参数类型对应                    
                                                                 //的类对象
        Object oo = cc.newInstance("王五",26);
        System.out.println(oo);//Person{name="王五", age=26}



    }
}
利用反射机制进行上述操作的步骤:
1:获取类对象
2:实例化对象
3:通过类对象获取要调用的方法对象
4:利用方法对象进行方法的调用
利用反射机制调用方法
    Method对象提供了调用该方法的操作:
    Object invoke(Object obj,Object[] args)
    参数1:当前Method对象表示的方法的所属对象
    参数2:该方法的实参列表
    返回值:实际调用该方法后该方法的返回值。
package reflect;

import java.io.File;
import java.lang.reflect.Method;


public class reflecT {
    public static void main(String[] args) throws Exception {
 
         

        Class cls = Class.forName(reflect.reflecT);

       
        Object o = cls.newInstance();//实例化对象

        Method method = cls.getMethod("hi");

        method.invoke(o);//调用该对象的对应方法

        //调用有参方法

    Class cc = Class.forName(reflect.reflecT);

    Object oo = cc.newInstance();

    Method methodd = cc.getMethod("hello",String.class,int.class);//参数类型,顺序,个数必                                                            
                                                                    须与方法一致     
                                                                                                                           
                                                           
    methodd.invock(o,"study",80);//实参的个数,类型,顺序也必须与方法定义一致








     }
}

通过反射机制可以调用私有方法

Class提供了对应的方法:

Method getDeclaredMethod(String method,Class... argsType)

Method[] getDeclearMethods()

hehe();是私有方法

package reflect;

import java.io.File;
import java.lang.reflect.Method;


public class reflecT {
    public static void main(String[] args) throws Exception {

        Class cl=Class.foeName("reflect.reflecT");

        Object obj=cl.newInstance();
 
        Method method =cl.getDeclaredMethod("hehe");
        method.setAccessible(true);//强行打开访问权限,此时下面就不会出现非法访问异常,并可调                        
                                     //用私有方法!!!

    //获取当前类定义的指定方法(可以获取本类定义的私有方法)

   // Method[] getDeclaredMethods()
    //获取当前类定义的所有方法(不包含从超类继承的)
    
    method.invoke(o);



}
}
操作属性
实际开发中,我们几乎不会对属性直接操作,都是借助于属性提供的get,set方法进行的。

反射中也差不多直接获取setxxx,getxxx方法后做后续的操作

package reflect;

import java.io.File;
import java.lang.reflect.Method;


public class reflecT {
    public static void main(String[] args) throws Exception {
    Class cls =Class.getName("reflect.reflecT);

    Object o =cls.newInstance();
    Method m =cls.getMethod("setname",String.class);
    
    m.invoke(o,"路非");
    
    
    
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值