黑马程序员关于反射机制总结

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

java反射机制是在运行状态中,对任意一个类,都能知道这个类的所有属性和方法;对任意一个对象,都能调用它的任意一个属性和方法,这种动态获取的信息以及动态调用对象的方法的功能称为java的反射机制。单单看这个定义我还是对反射有模糊,根据我的理解就是解剖一个类,对类中的属性和方法进行操作,首先要了解class类,通过以下3种方式获取类的字节码文件

1.对象.getClass, 此处的getClass是Object 类中的方法

package org.blog.test2;
class Child{ 
}
public class ReflectDemo {
 public static void main(String[] args) {
       Child c=new Child();
       System.out.println(c.getClass());//返回运行时的类
       System.out.println(c.getClass().getName()); //获取运行类的名称
 }
}

输出结果:class org.blog.test2.Child
org.blog.test2.Child

2.类.class 

public class ReflectDemo {
 public static void main(String[] args) {
       Class<Integer> clazz=Integer.class;      
       System.out.println(clazz);      
 }
}

输出结果:class java.lang.Integer

3.forName 不需要创建对象,只需要类的全名,但会抛出ClassNotFoundException,因为类的不确定性

public class ReflectDemo {
 public static void main(String[] args) {
  Class c=null;
  try {
   c=Class.forName("org.blog.test2.Child");
  } catch (ClassNotFoundException e) {   
   e.printStackTrace();  }
  System.out.print(c);
 }
}

输出结果:class org.blog.test2.Child

假设我现在有一个类,该如何调用类中私有或公有的属性及方法呢?比如说获取类中的构造函数,特点有参数列表,名称,修饰符,比较复杂,把它封装成对象操作起来较简单,Constructor,还有字段,有类型,有名称,有修饰符,有值,所以也封装成对象Field,还有Method,都封装成对象来操作,充分体现java中面向对象的思想。

package org.blog.test2;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

//定义一个被反射的类
class Child{
 private String name;
 private int age;
 Child(){
  System.out.print("child run");
 }
 public Child(String n,int a){
  this.setName(n);
  this.setAge(a);
  System.out.print("child run"+name+age);
 }

 public String show(){
  return "child show";
 }

 public void method(String name){
  System.out.print("method"+name);
 }

 private String privateMethod(){
  return "child method";
 }   

 public String getName(){
  return name;
 }
 public void setName(String n){
  this.name=n;
 }
 public int getAge(){
  return age;
 }
 public void setAge(int a){
  this.age=a;
 }
}

1.获取类的构造函数
public class ReflectDemo {
 public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
  Class<Child> clazz=(Class<Child>) Class.forName("org.blog.test2.Child");
  Object obj=clazz.newInstance();//newInstance调用类中空参的构造函数 
  System.out.println();
  Constructor constructor=clazz.getConstructor(String.class,int.class);//获取带参数的构造方法
  Object ob=constructor.newInstance("小明",23);  
 }
}

输出结果:child run
                     child run小明23

2.获取类中的字段

  public class ReflectDemo {
 public static void main(String[] args) throws Exception {
  Class<Child> clazz=(Class<Child>) Class.forName("org.blog.test2.Child");  
  Field field=clazz.getDeclaredField("age");
     field.setAccessible(true);//取消私有权限
     Object obj=clazz.newInstance();
     field.set(obj, 21);//设置字段值
     Object o=field.get(obj);//获取字段值
     System.out.print(o);
 }
}

输出结果:21

3.获取类中的方法

public class ReflectDemo {
 public static void main(String[] args) throws Exception {
  Class<Child> clazz=(Class<Child>) Class.forName("org.blog.test2.Child");  
  Method[] method=clazz.getMethods();//获取的都是公有的方法,包括Object类中的方法
  for (Method me : method) {
   System.out.println(me);
  }
  System.out.println("......................................................");
  Method[] methods=clazz.getDeclaredMethods();//只获取本类所有方法,包括私有
  for (Method me : method) {
   System.out.println(me);
  }
  System.out.println("......................................................");
  Method method1=clazz.getMethod("show", null);//获取指定的方法
  System.out.println(method1);
  System.out.println("......................................................");
  Object obj=clazz.newInstance();
  Method method2=clazz.getMethod("method", String.class);//获取带参数的方法
  method2.invoke(obj, "小明");
 }
}

输出结果:public void org.blog.test2.Child.setAge(int)
public int org.blog.test2.Child.getAge()
public java.lang.String org.blog.test2.Child.getName()
public void org.blog.test2.Child.setName(java.lang.String)
public java.lang.String org.blog.test2.Child.show()
public void org.blog.test2.Child.method(java.lang.String)
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
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 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()
......................................................
public void org.blog.test2.Child.setAge(int)
private java.lang.String org.blog.test2.Child.privateMethod()
public int org.blog.test2.Child.getAge()
public java.lang.String org.blog.test2.Child.getName()
public void org.blog.test2.Child.setName(java.lang.String)
public java.lang.String org.blog.test2.Child.show()
public void org.blog.test2.Child.method(java.lang.String)
......................................................
public java.lang.String org.blog.test2.Child.show()

......................................................
method小明

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值