反射基础

一,反射概念。

程序编写都是 .java–>(jvm) 编译成.class文件,反射也就是在.class文件里下手,类的所有信息在反射前面都是裸体,
一般好的框架都用到了反射(spring,mybatis)。

二,如何获取.class文件。

获取.class有三种方式
例:
先创建Student类。

public class Student {
   public   int sid;
    private  String sname;

第一种获取.class方式:

Student student=new Student();
        Class c= student.getClass();
        System.out.println(c);

第二种获取.class方式:

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

第三种方式,这个参数传递的是,你当前文件的.java的完整的包名加上类名(第三种是最常用的,一定要掌握)

 Class c3=  Class.forName("fanshe.com.offcn.pojo.Student");
          System.out.println(c3);

三,获取构造

得到这个对象,实例化对象肯定会走构造方法,
例:
首先在student类里创造,私有和公有的构造函数:

   public Student(int sid, String sname) {
        this.sid = sid;
        this.sname = sname;
    }

    public Student() {
    }

   private   Student(String sname) {
        this.sname = sname;
    }
    public  void  print(){
        System.out.println("调用成功");
    }
    private  String getString(String str){

        return  str;
    }

获取构造方法如下:

只获取公有的构造

  Constructor[] constructors = c3.getConstructors();
            for (int i=0;i<constructors.length;i++){
                System.out.println(constructors[i]);
            
            }

得到的结果为:

public fanshe.com.offcn.pojo.Student()
public fanshe.com.offcn.pojo.Student(int,java.lang.String)

这一种获取所有,getDeclaredConstructors获取私有 ,公有

 Constructor[] declaredConstructors = c3.getDeclaredConstructors();
            for (int i=0;i<declaredConstructors.length;i++){
                System.out.println(declaredConstructors[i]);
            }

得到的结果为:

public fanshe.com.offcn.pojo.Student()
public fanshe.com.offcn.pojo.Student(int,java.lang.String)
private fanshe.com.offcn.pojo.Student(java.lang.String)

四,获取实例化对象

首先在student类 写print();方法

 public  void  print(){
        System.out.println("调用成功");
    }

如果当前构造是无参的构造,默认一般都会给一个null;

 Constructor stuC= c3.getConstructor(null);

            //此句相当于 student stu=new student();
            //有参在里面写对应数值
            Object ob=stuC.newInstance(null);
            Student student1= (Student) ob;
            //调用方法
            student1.print();

里面的c3指上面
Class c3= Class.forName(“fanshe.com.offcn.pojo.Student”);里的c3

如果是有参 传对应参数的int.class String.class;

Constructor stuC= c3.getConstructor(int.class);

获取私有构造 区别在于getDeclaredConstructor,后续要使用setAccessible(true)来去除私有。

Constructor constructor= null;
 constructor = c2.getDeclaredConstructor(String.class);
            //通过暴力反射来去除私有
            constructor.setAccessible(true);
           Object ob= constructor.newInstance("3");
           Student student1= (Student) ob;
           student1.print();

五,获取属性。

在student类改变成以下情况:

   public   int sid;
    private  String sname;

获取所有公有属性

 //获取所有公有属性
          Field[] f= c2.getFields();
          for(int i=0;i<f.length;i++){
              System.out.println(f[i]);

结果如下:

public int fanshe.com.offcn.pojo.Student.sid

只是显示了公有部分

获取所有公私有

   Field[] f2= c2.getDeclaredFields();
            for(int i=0;i<f2.length;i++){
                System.out.println(f2[i]);
            }

结果为:

public int fanshe.com.offcn.pojo.Student.sid
private java.lang.String fanshe.com.offcn.pojo.Student.sname

六,获取私有属性,并赋值。

在student类里写get方法。

public String getSname() {
        return sname;
    }

然后获取私有属性,赋值方法如下:

 Field fieldName=  c2.getDeclaredField("sname");
            //暴力除去私有
            fieldName.setAccessible(true);
           
           Object o= c2.getConstructor().newInstance(null);
            //给其赋值,第一个参数是你要赋值的对象,第二个参数是你要赋的值
           fieldName.set(o,"zhi");
           //强转为Student类
           Student student2= (Student) o;
            System.out.println(student2.getSname());

结果为

zhi

七,获取所有公有、私有的方法。

//获取所有公有的方法
            //只要看见native方法,底层都是c或者c++编写的
           Method[] m = c2.getMethods();
           for (int i=0;i<m.length;i++){
               System.out.println(m[i]);
           }

结果为:
包含了父类的公有方法

public void fanshe.com.offcn.pojo.Student.print()
public void fanshe.com.offcn.pojo.Student.getInfo()
public java.lang.String fanshe.com.offcn.pojo.Student.getSname()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()

获取所有公私有的方法:

//获取所有的(包括公有和私有)的方法
c2.getDeclaredMethods ();

还有消除私有
constructor.setAccessible(true);
其他不变。

八,获取单个公有、私有的方法的方法,并调用其方法。

首先在student类,写getInfo方法。

public  void  getInfo(){
        System.out.println("这个getinfo正在被调用");
    }

获取单个公有的方法的方法,并调用其方法:

/获取单个公有的方法的方法,并调用其方法
           Method method= c2.getMethod("getInfo");
           //调用这个方法 invoke 第一个参数传递是你要调用这个方法的对象;
            //第二个参数是你要调用的这个方法的参数
            method.invoke(c2.getConstructor().newInstance(null));

其结果为: 这个getinfo正在被调用。

获取私有的单个方法,并调用其方法,首先在student类写 私有的getString();

 private  String getString(String str){

        return  str;
    }

随后在text类:

//获取私有的单个方法,并调用其方法
        Method method1= c2.getDeclaredMethod("getString",String.class);
        //去除私有
            method1.setAccessible(true);
            //调用其方法
        Object result=method1.invoke(c2.getConstructor().newInstance(null),"fanhuizhi");
            System.out.println(result);

其结果为:fanhuizhi

九,用反射来忽略泛型。

//用反射来忽略泛型
            List<String> list= new ArrayList<String>();
            list.add("a");
            list.add("b");
            list.add("c");


           //先获取其class文件
           Class  classList=list.getClass();
           //把String类,转换为了object类。只能小转大
             Method method2=classList.getMethod ("add",Object.class);
             
           method2.invoke (list,1);
            for (Object o2:list
                 ) {
                System.out.println (o2);
            }

结果为:

a
b
c
1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值