黑马程序员—反射

------- android培训java培训、期待与您交流! ----------

反射(Relfect)概述:

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象。

//创建一个被影射的类

package cn.itcast_01_Reflect;

/*

 * 人类

 */

public class Person {

public String name;

public int age;

private String address;

//构造方法

public Person() {

super();

}

private Person(String name) {

super();

this.name = name;

}

public Person(String name, int age, String address) {

super();

this.name = name;

this.age = age;

this.address = address;

}

//普通方法

//getXxx SetXxx

//没有返回值 没有参数的方法

public void method1(){

System.out.println("没有返回值 没有参数的方法");

}

//没有返回值, 有参数的方法

public void method2(String name){

System.out.println("没有返回值, 有参数的方法 name:" + name);

}

//有返回值,没有参数的方法

public int method3(){

System.out.println("有返回值,没有参数的方法");

return 12345;

}

//有返回值,有参数的方法

public String method4(String str){

System.out.println("有返回值,有参数的方法 , str:" + str);

return "day27" + str;

}

//私有方法

private void method5(){

System.out.println("我是私有方法, 呵呵");

}

@Override

public String toString() {

return "Person [name=" + name + ", age=" + age + ", address=" + address

+ "]";

}

}

package cn.itcast_01_Reflect;

/*

  Reflect 反射

  

  获取字节码文件对象的方式:

  

   方式1: 

   通过Object类中getClass()方法,  返回当前对象所对应的字节码文件对象 

   方式2:

    通过类名.class 完成  返回一个字节码文件对象

   方式3:(开发中使用)

    通过Class类中的forName()方法完成

    public static Class<?> forName(String className)  className需要使用的是 完整的类名称  包名.类名

 */

public class ReflectDemo {

public static void main(String[] args) throws ClassNotFoundException {

//方式1:

//Person p = new Person();

//Class c = p.getClass();

//System.out.println(c);

//方式2:

// Integer.class;

// int.class;

// String.class;

// char.class

//Class c2 = Person.class;

//System.out.println(c2);

//方式3

Class c3 = Class.forName("cn.itcast_01_Reflect.Person");

System.out.println(c3);

}

}

package cn.itcast_02_Reflect_Constructor;

 

import java.lang.reflect.Constructor;

import java.lang.reflect.InvocationTargetException;

 

import cn.itcast_01_Reflect.Person;

 

/*

  反射: 通过构造方法 创建对象

  

   方式1: 

   Person p = new Person();

   syso(p)

  

   方式2: 通过反射的方式 创建对象

   获取构造方法:

   获取所有的构造方法:

   public Constructor<?>[] getConstructors() 获取的是所有的public修饰的构造方法

 

   获取某一个构造方法:

   public Constructor<T> getConstructor(Class<?>... parameterTypes) 获取的是指定的public修饰的构造方法

Constructor类中的方法: 创建对象

public T newInstance(Object... initargs)

  参数: Object... initargs 创建对象的时候,要使用的具体参数数据。

 *  案例:  通过反射机制, 使用空参数构造方法 创建对象。

 */

public class ReflectDemo {

public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

//方式1

//Person p = new Person();

//System.out.println(p);

//方式2  通过反射的方式 创建对象

//a: 获取到字节码文件对象

Class c = Class.forName("cn.itcast_01_Reflect.Person");

//b: 获取到空参数构造方法

//获取所有的构造方法:public Constructor<?>[] getConstructors()

// Constructor[] cons = c.getConstructors();

// for (Constructor con : cons) {

// System.out.println(con);

// }

//public Constructor<T> getConstructor(Class<?>... parameterTypes)

//public Person() {}

Constructor con = c.getConstructor(null);

System.out.println(con);

//c: 通过空参数构造方法, 创建对象

//public T newInstance(Object... initargs)  

Object obj = con.newInstance(null);

System.out.println(obj);

}

}

package cn.itcast_02_Reflect_Constructor;

 

import java.lang.reflect.Constructor;

import java.lang.reflect.InvocationTargetException;

 

/*

  案例: 通过反射机制, 使用有参数构造方法,创建对象

  

  

  public Person(String name, int age, String address) {}

  

   方式1:

   Person p = new Person("小明", 20, "北京");

   syso(p)

   方式2:

   通过反射机制

 */

public class ReflectDemo2 {

public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

//获取Person类的字节码文件对象

Class c = Class.forName("cn.itcast_01_Reflect.Person");

//获取有参数的构造方法

Constructor con = c.getConstructor(String.class, int.class, String.class);

//通过构造方法,创建对象

Object obj = con.newInstance("小明", 20, "北京");

System.out.println(obj);

}

}

package cn.itcast_02_Reflect_Constructor;

 

import java.lang.reflect.Constructor;

import java.lang.reflect.InvocationTargetException;

 

/*

  通过反射机制, 使用私有的构造方法,创建对象

  

  

   private Person(String name) {}

  

   方式1: 不行

   Person p = new Person("小明");

   syso(p);

  

   方式2:可以 

    通过反射的方式

   

    构造方法的获取:

    多个构造方法:

    public Constructor<?>[] getDeclaredConstructors() : 获取所有的构造方法, 包含私有的

    指定的构造方法:

    public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 可以获取私有的构造方法

 

    AccessibleObject类

public void setAccessible(boolean flag) 取消java中 权限修饰符的检测

   

 */

public class ReflectDemo3 {

public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

//获取Person 类的字节码文件

Class c = Class.forName("cn.itcast_01_Reflect.Person");

//获取私有的构造方法

//多个构造方法:

//public Constructor<?>[] getDeclaredConstructors() : 获取所有的构造方法, 包含私有的

// Constructor[] cons = c.getDeclaredConstructors();

// for (Constructor con : cons) {

// System.out.println(con);

// }

//指定的构造方法:

//public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 可以获取私有的构造方法

Constructor con = c.getDeclaredConstructor(String.class);

//System.out.println(con);

//IllegalAccessException 非法的访问异常

//暴力 访问

//AccessibleObject

//public void setAccessible(boolean flag) 取消java中 权限修饰符的检测

con.setAccessible(true);

//创建对象

Object obj = con.newInstance("小明");

System.out.println(obj);

}

}

 

 

package cn.itcast_03_Reflect_Method;

 

import java.lang.reflect.Constructor;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

 

/*

 * 案例: 我想访问Person类中的无参数无返回值的方法

 *  public void method1(){

System.out.println("没有返回值 没有参数的方法");

}

方式1:

Person p = new Person();

p.method1();

方式2:

反射的方式

获取方法

多个方法

public Method[] getMethods() 获取所有的public 的方法, 包含父类中的public 方法

某一个方法

public Method getMethod(String name, Class<?>... parameterTypes)获取指定的public 的方法

 

执行方法,通过Method类中的方法

public Object invoke(Object obj, Object... args)

//参数: 

Object obj  执行的是哪个对象中的该方法

Object... args 方法的参数具体数据

 */

public class ReflectDemo {

public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

//获取Person类 字节码文件对象

Class c = Class.forName("cn.itcast_01_Reflect.Person");

//获取构造方法,创建对象

Constructor con = c.getConstructor(null);

Object obj = con.newInstance(null);

//获取到你想调用的方法

//public Method[] getMethods() 获取所有的public 的方法, 包含父类中的public 方法

// Method[] methods = c.getMethods();

// for (Method method : methods) {

// System.out.println(method);

// }

//public Method getMethod(String name, Class<?>... parameterTypes)获取指定的public 的方法

//public void method1(){}

Method method = c.getMethod("method1", null);

System.out.println(method);

//调用方法,并指定调用的是哪个对象中的该方法

//public Object invoke(Object obj, Object... args)

method.invoke(obj, null);

 

}

}

package cn.itcast_03_Reflect_Method;

 

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

 

/*

  案例: 我想访问Person类中的无参数无返回值的方法

  

   //有返回值,有参数的方法

public String method4(String str){}

 */

public class ReflectDemo2 {

public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {

//获取Person类字节码文件对象

Class c = Class.forName("cn.itcast_01_Reflect.Person");

//通过构造方法, 创建对象

Object obj = c.getConstructor(null).newInstance(null);

//获取指定的方法

Method method = c.getMethod("method4", String.class);

//执行方法

Object result = method.invoke(obj, "itcast0322");

System.out.println(result);

}

}

package cn.itcast_03_Reflect_Method;

 

import java.lang.reflect.Constructor;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

 

/*

  案例: 我想访问Person类中的私有方法

  

   方法的获取:

   多个方法:

   public Method[] getDeclaredMethods() 包含私有方法的获取

   注意: 该方法,只能获取到本类中的所有方法,包含私有的, 不能获取父类的方法

 

   某一个方法:

   public Method getDeclaredMethod(String name, Class<?>... parameterTypes) 包含私有方法的获取

 */

public class ReflectDemo3 {

public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

//获取字节码文件对象

Class c = Class.forName("cn.itcast_01_Reflect.Person");

//通过构造方法,创建对象

Constructor con = c.getConstructor(null);

Object obj = con.newInstance(null);

//获取指定的私有方法

//多个方法: public Method[] getDeclaredMethods() 包含私有方法的获取

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

// for (Method method : methods) {

// System.out.println(method);

// }

//某一个方法: public Method getDeclaredMethod(String name, Class<?>... parameterTypes) 包含私有方法的获取

//private void method5(){}

Method method = c.getDeclaredMethod("method5", null);

//暴力 访问

method.setAccessible(true);

//调用私有方法

method.invoke(obj, null);

}

}

package cn.itcast_04_Reflect_Field;

 

import java.lang.reflect.Constructor;

import java.lang.reflect.Field;

import java.lang.reflect.InvocationTargetException;

 

/*

  通过反射的方式, 获取指定的成员变量(字段)   public修饰的成员变量

  

   public String name;

  

  方式1:

   person p = new Person();

   syso(p);

   p.name = "小明";

   syso(p);

  

  方式2:

   反射的方式,来实现方式1的操作

  

   获取成员变量

   多个成员变量

   public Field[] getFields() 获取到所有的public 修饰的成员变量

   public Field[] getDeclaredFields() 可以获取所有的成员变量, 包含私有的

 

   某一个成员变量

   public Field getField(String name) 获取public 指定的成员变量

   public Field getDeclaredField(String name) 获取指定的成员变量,包含私有的

 

  

   Field类中的方法:

   public void set(Object obj, Object value) 为 指定对象中当前成员变量进行赋值

   public Object get(Object obj) 返回指定对象中 当前的成员变量值

 

 */

public class ReflectDemo {

public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {

// 获取Person字节码文件

Class c = Class.forName("cn.itcast_01_Reflect.Person");

// 通过构造方法,创建对象

Constructor con = c.getConstructor(null);

Object obj = con.newInstance(null);

// 获取指定的成员变量  name

//多个成员变量 public Field[] getFields()

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

// for (Field field : fields) {

// System.out.println(field);

// }

//某一个成员变量 public Field getField(String name)

//public String name;

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

Field fieldAge = c.getField("age");

//System.out.println(fieldName);

//获取私有的成员变量

//private String address 

Field fieldAddress = c.getDeclaredField("address");

System.out.println(obj);

// 使用成员变量

fieldName.set(obj, "小明");

fieldAge.set(obj, 20);

//使用私有的成员变量

fieldAddress.setAccessible(true);//开启暴力访问

fieldAddress.set(obj, "上海");

System.out.println(obj);

}

}

package cn.itcasty_05_Reflect_Test;

 

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

import java.util.ArrayList;

 

/*

  反射 在现实开发中的使用

  

  泛型的擦除技术:

   泛型的约束它只能够在编译器有效,当编译通过后,产生了一个.class字节码文件,

   该字节码文件中,没有泛型

  

   注意: 那么,当我们使用反射技术的时候,所有的类中都是没有泛型约束的

 */

public class ReflectTest {

public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

ArrayList<Integer> list =new ArrayList<Integer>();

list.add(20);

list.add(30);

list.add(40);

//由于集合中的泛型为Integer类型,所以我们不能存储其他类型

//list.add("哈哈");

//获取字节码文件对象

//Class c = Class.forName("java.util.ArrayList");

Class c = ArrayList.class;

//通过构造方法,创建对象

//list 对象有了, 不需要创建

//获取指定的方法

//public boolean add(E e) 

Method methodAdd = c.getMethod("add", Object.class);

//执行方法

methodAdd.invoke(list, "哈哈");

System.out.println(list);

}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值