Java基础:反射

1、反射的两个作用

A、获取类的信息

B、动态调用对象成员

 

2、类加载到内存后,JVM会为该类创建一个Class对象,用于保存类中的信息:

  •      所在的包
  •      父类
  •      接口
  •      成员变量
  •      成员方法
  •      构造方法

     通过反射,可以读取类中的全部信息(除了方法体)

 

3、Class c =  Class.forName() : 将类加载到内存,但是不实例化

   如果要实现化,调用c.newInstance()来完成实例化工作

   创建对象的两种方法:

方法一:

String s = new String("韬睿"); //将String类加载到内存,然后实例化

方法二:

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

Object s = c.newInstance();

 

4、案例:Java中创建对象的几种方法

public class Student implements Cloneable{
     private int sid;
     private String name;
    
     public Student() {
          System.out.println("构造方法");
     }

     public Student(int sid, String name) {
          super();
          this.sid = sid;
          this.name = name;
          System.out.println("构造方法");
     }

     @Override
     public String toString() {
          return "Student [sid=" + sid + ", name=" + name + "]";
     }

     @Override
     public Object clone() throws CloneNotSupportedException {
          return super.clone();
     }
}


public class ObjectDemo {
     public static void main(String[] args) throws Exception {
          //通过new关键字
          Student s1 = new Student(1, "张三");
          System.out.println(s1);
         
          //通过反射
          Class c = Class.forName("com.tr.ref.Student");
          Object s2 = c.newInstance();
          System.out.println(s2);
         
          //采用克隆技术
          Object s3 = s1.clone();
          System.out.println(s3);
         
          System.out.println(s1 == s3);
     }
}

 

5、获得Class对象的几种方法

A、通过字符串

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

B、通过类的class属性

     Class c = Date.class;

C、通过对象的getClass()方法

     Class c = new Date().getClass();

D、基本类型

     Class c = int.class;

 

6、通过Class可以获取其他数据

     所在的包     

          Package pck = c.getPackage();

     父类         

          Class superClass = c.getSuperClass();

     接口

          Class[] interfaces = c.getInterfaces();

     成员变量

          Field[] fields = c.getFields();//public

          Field[] fields = c.getDeclaredFields();//all

     成员方法

          Method[] methods = c.getMethods();//public、父类         

          Method[] methods = c.getDeclaredMethods();//all

     构造方法

          Constructor[] cons = c.getConstructors();

 

7、反射提供了一种操作对象成员的另一种方式

 

8、通过反射访问对象的成员变量

A、获得成员变量Field对象

     Field f = c.getDeclaredField("name");

B、Field的set()方法用于给成员变量赋值

C、Field的get()方法用于获取成员变量的值

此方法的作用等同于:

Student s = new Student(); //创建对象

s.name = "张三";//给属性赋值

String name = s.name;//取出属性的值

 

完成属性的访问操作需要对象、属性名和属性值

反射实现:

Class c = Class.forName("com.tr.ref.Student");//加载类

Object stu = c.newInstance();//创建对象

Field name = c.getField("name");

name.set(stu, "张三");

Object n= name.get(stu);

 

使用反射可以增强程序的可配置性和扩展性

 

9、通过反射访问对象的成员方法

A、获取Method对象

     Method method = c.getDeclaredMethod("方法名", A.class, B.class);

     比如:     

    

    Method play = c.getDeclaredMethod("play", int.class, int.class, String.class);

 

B、通过Method.invoke(Object obj, 参数值列表)来调用方法

play.invoke(stu, 1, 2, "小猫");

传统做法:

Student stu = new Student();

stu.play(1, 2, "小猫");

反射做法:

Class c = Class.forName("com.tr.ref.Student");//加载类

Object stu = c.newInstance();//创建对象

//获得方法对象

Method play = c.getDeclaredMethod("play", int.class, int.class, String.class);

//调用方法

play.invoke(stu, 1, 2, "小猫");

 

10、练习

     定义一个员工类,有姓名和出生日期两个属性,有上班的方法(参数为小时)     

public class Employee{

          public String name;

          public Date birthday;

          public void doWork(int hour){

               Sysout.out.println("工作了" + hour + "小时";

          }

     }

     请使用反射完成下面的功能:

     A)给员工对象的name和birthday属性赋值并打印出来

     B)调用doWork方法

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值