反射

 

反射

 

 1.获取Class对象:
  Class类是用来描述一个类的类, 当程序运行时虚拟机加载.class文件到内存中, 在内存中这些.class文件就是Class类的对象.
  我们如果获得了Class对象, 就可以使用这个对象的newInstance()方法来创建该类的实例.
  获取Class对象的方式有3种:
   a.通过字符串获取: Class.forName(String)
   b.通过类名直接获取: 类名.class
   c.通过对象获取: 对象.getClass()

 


import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/*
 * Person 类用来描述人
 * Student 类用来描述学生
 * String 类用来描述字符串
 * Class 类用来描述所有的.class文件
 */
public class ClassDemo {

 public static void main(String[] args) throws Exception {
  //  demo1();
  //  demo2();
  //  demo3();
  //  demo4();
 }

 private static void demo4() throws ClassNotFoundException {
  Apple apple = new Apple();

  Class clazz1 = Class.forName("cn.itcast.day29.reflect.Apple");
  Class clazz2 = Apple.class;
  Class clazz3 = apple.getClass();

  System.out.println(clazz1);
  System.out.println(clazz2);
  System.out.println(clazz3);

  System.out.println(clazz1 == clazz2);
  System.out.println(clazz2 == clazz3);

  // 以上3种方式获取的都是Apple类, 是同一个对象
 }

 private static void demo3() throws InstantiationException, IllegalAccessException {
  //
  Object obj = new Apple();
  Class<?> clazz = obj.getClass();
  //执行完上面两步后,就可以获得一个Class对象
  //使用这个Class对象就可以创建Apple对象了
  Fruit fruit = (Fruit) clazz.newInstance();
  fruit.squeeze();
 }

 private static void demo2() throws InstantiationException, IllegalAccessException {
  Class<?> clazz = Apple.class;
  Fruit fruit = (Fruit) clazz.newInstance();
  fruit.squeeze();
 }

 private static void demo1() throws FileNotFoundException, ClassNotFoundException, IOException, InstantiationException, IllegalAccessException {
  BufferedReader br = new BufferedReader(new FileReader("config.txt"));

  // 获取到一个Class对象
  Class clazz = Class.forName(br.readLine());

  // 通过Class对象创建该类的一个实例
  Fruit fruit = (Fruit) clazz.newInstance();

  // 调用该对象的方法
  fruit.squeeze();
 }

}

 

 

 

 

 2.构造函数Constructor:
  如果一个Class对象中有无参构造函数, 那么可以直接使用Class对象的newInstance()方法来创建对象.
  但是如果没有无参的构造函数, 那么就需要调用其有参的构造函数来创建对象了.
  使用Class类的getConstructor(Class...)方法获取到指定的构造函数.
  通过Construtor类的newInstance(Object...)方法来调用构造函数创建对象.

 


import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import cn.itcast.day29.domain.Person;

/*
 * 一个类如果有无参的构造函数, 可以直接使用Class的newInstance()来创建对象
 * 如果没有无参的构造函数, 那么必须调用指定一个构造函数
 */
public class ConstructorDemo {

 public static void main(String[] args) throws Exception {
  //  demo1();
  //  demo2();

  //  Person p = new Person("张三", 'a'); // JDK5之后基本数据类型和他们的包装类之间可以自动装箱自动拆箱
  //  System.out.println(p);
 }

 private static void demo2() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
  Class<?> clazz = Class.forName("cn.itcast.day29.domain.Person");

  clazz.newInstance();

  // 获取无参的构造函数
  Constructor c = clazz.getConstructor();

  // 通过无参构造函数创建对象
  System.out.println(c.newInstance());
 }

 private static void demo1() throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
  

  // 获取该类中所有的构造函数
  // Constructor[] arr = clazz.getConstructors();
  Class<?> clazz = Class.forName("cn.itcast.day29.domain.Person");
  // 获取参数类型为String和int的构造函数
  Constructor c = clazz.getConstructor(String.class, int.class);
  // 调用这个构造函数创建一个Person对象
  Person p = (Person) c.newInstance("张三", 19);

  System.out.println(p);
 }

}

 

 

 


 

 

3.方法Method:
  我们可以通过Class对象获取一个类中的方法. 获取到方法之后可以运行该方法.
  可见的方法:
   通过Class类的getMethod(String, Class...)方法获取指定的方法.
   通过Method的invoke(Object, Object...)方法调用该方法.
  类中定义的方法(包括不可见的):
   通过Class类的getDeclaredMethod(String, Class...)方法获取到该类定义的一个方法
   如果该方法是一个不可见的方法, 那么需要设置该方法的可见性, setAccessible(boolean)

 

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

@SuppressWarnings( { "unused", "unchecked" })
public class MethodDemo {

 public static void main(String[] args) throws Exception {
  //  demo1();
  //  demo2();

  //  demo3();
  //  demo4();
 }

 private static void demo4() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
  Class clazz = Class.forName("cn.itcast.day29.domain.Person");
  Object obj = clazz.newInstance();

  // 获取该类中定义的方法, 包括私有的方法
  Method sleepMethod = clazz.getDeclaredMethod("sleep");

  // 设置访问权限
  sleepMethod.setAccessible(true);

  // 调用该方法
  sleepMethod.invoke(obj);
 }

 private static void demo3() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
  Class clazz = Class.forName("cn.itcast.day29.domain.Person");

  // 获取该类中定义的方法
  Method[] arr = clazz.getDeclaredMethods();
  for (Method method : arr) {
   System.out.println(method);
  }
 }

 private static void demo2() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
  Class clazz = Class.forName("cn.itcast.day29.domain.Person");
  Object obj = clazz.newInstance();

  // 获取名为"run", 没有任何参数的方法
  Method runMethod = clazz.getMethod("run");

  // 运行该方法
  runMethod.invoke(obj);

  // 获取setName(String)方法
  Method setNameMethod = clazz.getMethod("setName", String.class);

  // 调用该方法设置name
  setNameMethod.invoke(obj, "李四");

  runMethod.invoke(obj);
 }

 private static void demo1() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
  Class clazz = Class.forName("cn.itcast.day29.domain.Person");

  // 获取该类所有可见的方法, 可以调用到的
  Method[] arr = clazz.getMethods();
  for (Method method : arr)
   System.out.println(method);
 }

}

 

 

 

 

 

 4.属性Field:
  我们可以通过Class对象获取该类中的属性, 可以设置或获取该属性的值.
  可见的属性:
   通过Class对象的getField(String)方法获取到Field对象
   通过Field对象的set(Object, Object)设置该属性的值
  类中定义的(包括不可见的):
   通过Class对象的getDeclaredField(String)方法获取到Field对象
   如果该属性是不可见的, 那么需要设置可见性才能操作. setAccessible(boolean)
   

import java.lang.reflect.Field;

public class FieldDemo {

 public static void main(String[] args) throws Exception {
  //  demo1();
  //  demo2();
  //  demo3();
 }

 private static void demo3() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
  Class clazz = Class.forName("cn.itcast.day29.domain.Person");
  Object obj = clazz.newInstance();

  // 获取指定的属性
  Field nameField = clazz.getDeclaredField("name");
  // 修改访问权限
  nameField.setAccessible(true);
  // 为该属性赋值
  nameField.set(obj, "王五");

  Field ageField = clazz.getDeclaredField("age");
  ageField.setAccessible(true);
  ageField.set(obj, 20);

  // 获取obj对象上nameField的值
  System.out.println(nameField.get(obj));
  System.out.println(ageField.get(obj));
 }

 private static void demo2() throws ClassNotFoundException {
  Class clazz = Class.forName("cn.itcast.day29.domain.Person");
  // 获取该类中定义的属性
  Field[] fields = clazz.getDeclaredFields();
  for (Field field : fields)
   System.out.println(field);
 }

 private static void demo1() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
  Class clazz = Class.forName("cn.itcast.day29.domain.Person");
  // 获取该类中所有可见的属性
  Field[] fields = clazz.getFields();
  System.out.println(fields.length);
 }

}

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值