黑马程序员_反射
来源:互联网 发布:淘宝女士连衣裙 编辑:程序博客网 时间:2024/05/17 04:11
------- android培训、java培训、期待与您交流! ----------
反射的概念:
反射就是把Java类中的各种成分映射想成Java类。通过class文件的对象,获取构造函数、字段、方法的操作。
例如:众多的人用一个Person类表示,那么众多的Java类就用一个Class类表示。
反射也称之为对类的解剖。把类的各个组成部分映射成一个个相应的Java类。
学习反射的目的:
有些时候,可能JDK中的方法没有在帮助文档中提供,但是通过查看源代码,却发现有这个方法,不会该方法为private私有,所
以JDK的帮助文档没有提供该方法。如果必须使用这个方法,我们可以通过反射的方式来获取,进行使用。
得到某个class文件相对应的class对象的方法有3中:
1、getClass():返回进行时的类。
例如:new Date().getClass()。
2、数据类型.class:静态属性,来获取当前数据类型的自解码文件对象。
例如:Person.class.
3、public static Class forName(String className):返回与带有给定字符串名的类或接口相关联的Class对象。
例如:Class.forName("java.long.String");
代码示例:
注意:字节码文件是唯一的,无论怎么获取,都是同一份字节码文件。
Constructor类的实例化对象代表类的一个构造方法。
public Constructor[] getCOnstructors():反射所有的公共的构造方法
public Constructor[] getDeclaredConstructors():获取所有的构造函数(包含私有)
public Constructor getContructor(Class<?>... parameterTypes):获取指定的构造函数
public Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes):获取指定的构造函数(包含私有)
public void setAccessible(boolean flag):是否可以访问(暴力访问)
public Object newInstance(Object... initargs):使用此Constructor对象表示的构造方法来创建该构造方法的声明类的新实例,并用于指定的初始化该实例。
步骤:
a:创建一个Class字节码文件对象
b:获取指定的构造函数 如果是非public的构造函数,需要 强制访问(暴力访问)
c:创建对象
例如:
由结果可知:public Constructor[] getCOnstructors():反射所有的公共的构造方法 public Constructor[] getDeclaredConstructors():获取所有的构造函数(包含私有)
成员变量的反射(Field类):
Class中的方法:
public Field[] getFields() : 获取 public 修饰的 所有字段
public Field[] getDeclaredFields(): 获取所有的字段(包含私有)
public Field getField(String name): 获取指定的字段
public Field getDeclaredField(String name): 获取指定的字段(包含私有)
Field中的方法:
public void set(Object obj, Object value): 为指定对象中的当前字段, 赋值
步骤:
a: 创建class字节码文件对象
b: 获取指定的字段,如果是非public 修饰的字段, 需要 暴力访问
c: 对字段进行操作
举例验证上述方法:
public Method[] getMethods() 获取所有的公共方法(包含父类的)
public Method[] getDeclaredMethods() 获取所有的方法(不包含父类)
public Method getMethod(String name, Class<?>... parameterTypes) : 获取指定的方法
public Method getDeclaredMethod(String name, Class<?>... parameterTypes) : 获取指定的方法(包含私有的)
Method类的方法:
public Object invoke(Object obj, Object... args)
调用给定的对象中的当前方法,并且给定方法的参数列表,这个时候就可以确定调用的是具体的哪一个方法了
public void setAccessible(boolean flag)
步骤:
a: 创建class 字节码文件对象
b: 获取指定的方法
c: 使用方法(需要前有对象,才能使用方法)
举例验证上述方法:
反射就是把Java类中的各种成分映射想成Java类。通过class文件的对象,获取构造函数、字段、方法的操作。
例如:众多的人用一个Person类表示,那么众多的Java类就用一个Class类表示。
反射也称之为对类的解剖。把类的各个组成部分映射成一个个相应的Java类。
学习反射的目的:
有些时候,可能JDK中的方法没有在帮助文档中提供,但是通过查看源代码,却发现有这个方法,不会该方法为private私有,所
以JDK的帮助文档没有提供该方法。如果必须使用这个方法,我们可以通过反射的方式来获取,进行使用。
得到某个class文件相对应的class对象的方法有3中:
1、getClass():返回进行时的类。
例如:new Date().getClass()。
2、数据类型.class:静态属性,来获取当前数据类型的自解码文件对象。
例如:Person.class.
3、public static Class forName(String className):返回与带有给定字符串名的类或接口相关联的Class对象。
例如:Class.forName("java.long.String");
代码示例:
public class ClassTest {public static void main(String[] args) throws ClassNotFoundException {String s = "黑马";//数据类型.class:静态属性,来获取当前数据类型的自解码文件对象,Class c1 = String.class;//getClass():返回进行时的类,Class c2 = s.getClass();//Class.forName(String className)返回与带有给定字符串名的类或接口相关联的Class对象。Class c3 = Class.forName("java.lang.String");System.out.println(c1 == c2);System.out.println(c2 == c3);}}
注意:字节码文件是唯一的,无论怎么获取,都是同一份字节码文件。
public class Person {private String name;int age;public String address;public Person(){}private Person(String name){this.name = name;}Person(String name, int age){this.name = name;this.age = age;}public Person(String name, int age, String address){this.name = name;this.age = age;this.address = address;}public void show(){System.out.println("show");}public void method(String s){System.out.println(s);}public String function(){return "function";}public int sum (int x, int y) {return x+y;}private void method(){System.out.println("私有的method");}@Overridepublic String toString() {return "Person [name=" + name + ", age=" + age + ", address=" + address+ "]";}}构造方法的反射应用(Constructor类):
Constructor类的实例化对象代表类的一个构造方法。
public Constructor[] getCOnstructors():反射所有的公共的构造方法
public Constructor[] getDeclaredConstructors():获取所有的构造函数(包含私有)
public Constructor getContructor(Class<?>... parameterTypes):获取指定的构造函数
public Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes):获取指定的构造函数(包含私有)
public void setAccessible(boolean flag):是否可以访问(暴力访问)
public Object newInstance(Object... initargs):使用此Constructor对象表示的构造方法来创建该构造方法的声明类的新实例,并用于指定的初始化该实例。
步骤:
a:创建一个Class字节码文件对象
b:获取指定的构造函数 如果是非public的构造函数,需要 强制访问(暴力访问)
c:创建对象
例如:
import java.lang.reflect.Constructor;public class ReflectDemo {public static void main(String[] args) throws ClassNotFoundException {//获取Person类的字节码文件对象Class c = Class.forName("com.itheima_02.Person");//public Constructor[] getConstructors() Constructor[] cons = c.getConstructors();for(Constructor con : cons){System.out.println(con);}System.out.println("-----------------");Constructor[] cons1 = c.getDeclaredConstructors(); for(Constructor con : cons1){ System.out.println(con); }}}其结果为:
由结果可知:public Constructor[] getCOnstructors():反射所有的公共的构造方法 public Constructor[] getDeclaredConstructors():获取所有的构造函数(包含私有)
成员变量的反射(Field类):
Class中的方法:
public Field[] getFields() : 获取 public 修饰的 所有字段
public Field[] getDeclaredFields(): 获取所有的字段(包含私有)
public Field getField(String name): 获取指定的字段
public Field getDeclaredField(String name): 获取指定的字段(包含私有)
Field中的方法:
public void set(Object obj, Object value): 为指定对象中的当前字段, 赋值
步骤:
a: 创建class字节码文件对象
b: 获取指定的字段,如果是非public 修饰的字段, 需要 暴力访问
c: 对字段进行操作
举例验证上述方法:
import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;public class ReflectDemo {public static void main(String[] args) throws <span style="font-size:14px;"><span style="font-family:Simsun;"><span style="font-size:14px;"><span style="font-family:Simsun;"><span style="color:#330033;"><span style="LINE-HEIGHT: 21px"></span></span></span></span></span></span>Exception<span style="font-size:14px;"><span style="font-family:Simsun;"><span style="font-size:14px;"><span style="font-family:Simsun;"><span style="color:#330033;"><span style="LINE-HEIGHT: 21px"></span></span></span></span></span></span> {// 创建class字节码文件对象Class c = Class.forName("com.itheima_02.Person");//创建构造函数并创建对象Constructor con = c.getDeclaredConstructor();Object obj = con.newInstance();// Person//public Field[] getFields()Field[] fields = c.getFields();for (Field field : fields) {System.out.println(field);}System.out.println("-------");//public Field[] getDeclaredFields()Field[] fields1 = c.getDeclaredFields(); for (Field field : fields1) { System.out.println(field); }//public Field getField(String name): 获取指定的字段Field addressField = c.getField("address");System.out.println(obj);//public void set(Object obj, Object value): 为指定对象中的当前字段, 赋值addressField.set(obj, "北京");//private String name;Field nameField = c.getDeclaredField("name");nameField.setAccessible(true);//暴力访问nameField.set(obj, "黑马");System.out.println(obj);}}其结果为:
成员方法的反射(Method类):
Class类中的方法:public Method[] getMethods() 获取所有的公共方法(包含父类的)
public Method[] getDeclaredMethods() 获取所有的方法(不包含父类)
public Method getMethod(String name, Class<?>... parameterTypes) : 获取指定的方法
public Method getDeclaredMethod(String name, Class<?>... parameterTypes) : 获取指定的方法(包含私有的)
Method类的方法:
public Object invoke(Object obj, Object... args)
调用给定的对象中的当前方法,并且给定方法的参数列表,这个时候就可以确定调用的是具体的哪一个方法了
public void setAccessible(boolean flag)
步骤:
a: 创建class 字节码文件对象
b: 获取指定的方法
c: 使用方法(需要前有对象,才能使用方法)
举例验证上述方法:
import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class ReflectDemo2 {public static void main(String[] args) throws Exception {//创建class 字节码文件对象Class c = Class.forName("com.itheima_02.Person");//public Method[] getMethods() publicMethod[] methods = c.getMethods();for (Method method : methods) {System.out.println(method);}System.out.println("--------");//public Method[] getDeclaredMethods() 所有的Method[] methods1 = c.getDeclaredMethods(); for (Method method : methods1) { System.out.println(method); }/* * Person p = new Person(); * p.show(); */Constructor con = c.getConstructor();Object obj = con.newInstance();// Person//获取指定的方法//public Method getMethod(String name, Class<?>... parameterTypes) : 获取指定的方法Method showMethod = c.getMethod("show",null); //System.out.println(showMethod);//使用方法//public Object invoke(Object obj, Object... args)//调用给定的对象中的当前方法,并且给定方法的参数列表,这个时候就可以确定调用的是具体的哪一个方法了showMethod.invoke(obj, null);System.out.println("-----------------------------------------");//public void method(String s){}//public Method getMethod(String name, Class<?>... parameterTypes) : 获取指定的方法Method meMethod = c.getMethod("method", String.class);//public Object invoke(Object obj, Object... args)meMethod.invoke(obj, "黑马");System.out.println("-----------------------------------------");//public String function(){}Method functionMethod = c.getMethod("function", null);String str = (String) functionMethod.invoke(obj,null);System.out.println(str);System.out.println("-----------------------------------------");//public int sum (int x, int y) {}Method sumMethod = c.getMethod("sum", int.class, int.class);int sum = (int) sumMethod.invoke(obj, 22, 11);System.out.println(sum);System.out.println("-----------------------------------------");//private void method(){}//Method me2Method = c.getMethod("method", null);Method me2Method = c.getDeclaredMethod("method", null);//暴力点me2Method.setAccessible(true);me2Method.invoke(obj, null);}}其结果为:
------- android培训、java培训、期待与您交流! ----------
0 0
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员_反射
- 如何让平滑细分只平滑一个物体的一部分,而其他部分不受影响
- java 线程 原子类相关操作示例 thinking in java4 目录21.3.4
- Cf386B
- LeetCode -- sameTree
- C/C++内存分配
- 黑马程序员_反射
- Caused by: java.lang.ClassNotFoundException: org.apache.commons.lang3.StringUtils
- 幸福资本信用卡客户群
- Cf387A
- 研发之道(8)架构设计漫谈(三)时钟和复位
- Cf393A
- 留个纪念
- Android Camera API 使用指南
- 初试安装storm