黑马程序员--03.反射--03【反射获取构造方法】
来源:互联网 发布:怎样发数据到gsm模块 编辑:程序博客网 时间:2024/05/28 01:34
反射----3
反射获取构造方法
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
1. 通过反射获取Class的构造方法
1). 通过反射获取类的默认空参构造函数
(1). Class类的newInstance()方法
newInstance( )方法的源码声明:
public T newInstance() throws InstantiationException,IllegalAccessException;
(2). 通过Class的newInstance() 方法建立类对象
【示例代码】
//1. 通过Class对象的newInstance()方法调用类的默认空参构造方法public static void getConstructor1(){ try{ Stringname ="cn.itcast.bean.Person"; Classclazz =Class.forName(name); Objectobj = clazz.newInstance(); }catch(ClassNotFoundException cnfe){ sop(cnfe.toString()); }catch(InstantiationException ite){ sop(ite.toString()); }catch(IllegalAccessException iae){ sop(iae.toString()); }}
打印结果:Person run… [这个是Person类的默认构造函数]
[2]. 优势:
通过Class类对象的newInstance( )来创建Class类对象对应的类的实例好处就是:
{1}. 仅仅以字符串的形式将cn.itcast.bean.Person这个类名传递给Class的静态方法forName之后,就可以创建Person类的对象。
{2}. 应用的时候,就将“cn.itcast.bean.Person”暴露到配置文件中,非常方便。程序的可扩展性很强。
[3]. 通过Class类对象的newInstance( )方法调用的是Class类对象所属类的默认空参构造函数。
(3). Class类的newInstance()抛出的两种异常
[1]. InstantiationException
Class;类对象所属的类如果没有默认空参构造函数,但是又调用了Class类对象的newInstance( )方法的时候,会抛出java.lang.InstantiationException
【示例】
Person类:没有默认空参构造函数
package cn.itcast.bean;public class Person { private int age; private String name; public Person(String name, int age){ super(); this.age =age; this.name =name; System.out.println("Person param run..."+ this.name+":" + this.age);}}
测试类中:
String name ="cn.itcast.bean.Person";Class clazz =Class.forName(name);Object obj = clazz.newInstance();
抛出异常如下:
[2]. IllegalAccessException
当实体类中的默认空参构造函数的访问权限是private而不是public的时候,通过Class的newInstance( )方法会抛出异常:java.lang.IllegalAccessException
【示例代码】
Person类:Person()访问权限私有化
public class Person { private int age; private String name; private Person(){ System.out.println("Person run..."); } public Person(String name, int age){ super(); this.age =age; this.name =name; System.out.println("Person param run..."+ this.name+":" + this.age); }}
测试类:
String name ="cn.itcast.bean.Person";Class clazz =Class.forName(name);Object obj = clazz.newInstance();
抛出如下异常:
java.lang.IllegalAccessException: Class ReflectDemoII can not accessa member of class cn.itcast.bean.Person with modifiers "private"
2). 通过反射获取类的指定构造函数
(1). 构造函数类java.lang.reflect.Constructor
[1]. Constructor所在的位置
在java语言包的反射子包java.lang.reflect中含有反射用到的类Constructor。
[2]. Constructor类描述的事物
Constructor类抽象的是各个类的构造函数的总体。
[3]. Constructor类的源码声明
public final classConstructor<T>…{…}
【结论】Constructor是不可以被继承的泛型类
(2). 获取构造函数类Constructor对象的方式
实体类代码:
public class Student extends Person{ public Student(String name, int age){ super(name, age); }}
/////////////////////////////////////////////////
Class类对象有3种方法可以获取到Constructor类对象。
[1]. Class类的getConstructors()方法
public Constructor<?>[]getConstructors()throws SecurityException
{1}. 参数说明:返回值类型是构造函数对象数组Constructor<?>[]
数组中每个元素的类型是Constructor<?>,使用了泛型通配符。本以为可以返回父类构造,因为使用的是<?>。但是运行含有继承关系的类的代码没有发现有父类的构造函数输出。所以,我觉得应该是Constructor<T>
{2}. 测试代码:
Class clazz =Class.forName("cn.itcast.bean.Student");Constructor[] cons=clazz.getConstructors();for(Constructor con: cons){ System.out.println(con);}
打印结果:
publiccn.itcast.bean.Student(java.lang.String,int)
[2]. Class类的getDeclaredConstructors()方法
public Constructor<?>[]getDeclaredConstructors() throws SecurityException
{1}. 参数说明:返回值类型依旧是含有通配符的构造函数类对象数组Constructor<?>[]
{2}. 测试代码:
Class clazz =Class.forName("cn.itcast.bean.Person");Constructor[] cons=clazz.getConstructors();Constructor[] consI=clazz.getDeclaredConstructors();for(Constructor con: consI){ System.out.println(con);}
打印结果:
private cn.itcast.bean.Person()
publiccn.itcast.bean.Person(java.lang.String,int)
[3]. Class类的 getConstructor(Class<?>... parameterTypes)方法
public Constructor<T> getConstructor(Class<?>...parameterTypes) throws NoSuchMethodException,SecurityException
参数说明:
{1}1. 输入参数:Class<?>... parameterTypes<===>Class<?>[]parameterTypes
使用可变参数数组原因:只有一个参数 (一定是最后一个参数) ,又是数组===>变成可变参数数组。
数组中的每个元素类型是Class<?>,原因是每一种不同类型的构造函数都有不同类型的参数。每一种参数对应自己不同的字节码文件,也就是不同的Class对象。所以Class<?>可以接受各种类对应的字节码文件。所以不用Class<T>而是用Class<?>
{1}2. 返回值类型:Constructor<T>:因为你是要返回这个Class对象所属的类的指定的Constructor,所以应该写成Constructor<T>而不是Constructor<?>
(3). 调用Constructor这个类对象的newInstance()方法来构造实例
[1]. Constructor类的newInstance( )方法的源码声明
public T newInstance(Object ... initargs)…;
[2]. 参数类型
{1}. 输入值类型:Object ... initargs ===>可变参数数组Object[]
数组中元素的类型是Object而不是T的原因是:
获取Constructor对象之后,是要向这个指定的构造函数对象中传递参数的。具体传递什么参数不知道,所以只能多态统一成Object。没有将Object升华为T的原因是,T是Constructor的类型,也就是Constructor对象所在的字节码文件中的构造函数。这个T代表对应的类的类型。这个T和newInstance中的参数类型含义不同。所以不可以。
{2}. 返回值类型T:正好是要创建实例对象的类型。
{3}. 示例代码:
//2. 通过Class对象的getConstructor()方法获取指定的参数的构造方法,之后再通过这个构造方法对象的newInstance() //来实例化对象public static void getConstructor2(){ try{ Stringname ="Person"; Classclazz =Class.forName(name); Constructorconstructor = clazz.getConstructor(String.class, int.class); Objectobj =constructor.newInstance("Benjamin", 28); }catch(ClassNotFoundException cnfe){ sop(cnfe.toString()); }catch(InstantiationException ite){ sop(ite.toString()); }catch(IllegalAccessException iae){ sop(iae.toString()); }catch(NoSuchMethodException nse){ sop(nse.toString()); }catch(InvocationTargetException ite){ sop(ite.toString()); }}
运行结果:Person param run...Benjamin:28
2. new创建对象 VS 反射创建对象
1). 使用反射调用默认无参构造函数创建对象
(1). 步骤
[1]. 通过Class类的方法newInstance()方法建立对象的步骤
step1:通过以字符串形式给出的全类名 ===>获取Class对象
step2:调用Class对象的newInstance()方法来实例化Class对象对应类的实例
(2). 与new创建对象的关系
【结论】无论是new建立对象还是反射建立对象,JVM执行的步骤是一样的,只不过代码的表现形式不一样。
2). 使用反射调用指定参数构造函数创建对象
(1). 步骤
通过Constructor类的方法newInstance(Object…initArgs)方法建立对象的步骤
step1:通过以字符串形式给出的全类名 ===>获取Class对象
step2:调用Class对象的getConstructor()方法来该类指定的构造函数类Constructor类的对象
step3:调用Constructor对象的newInstance(Object…initArgs)方法构建对象。
(2). 指定参数构造和使用无参构造的区别
利用反射调用指定构造函数的步骤比利用反射调用默认构造函数的步骤多一步获取Constructor的步骤,别的都一样。
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
- 黑马程序员--03.反射--03【反射获取构造方法】
- 黑马程序员--03.反射--05【反射获取成员方法】
- 黑马程序员——高新技术(反射,用反射获取构造函数、方法等)
- 黑马程序员——【Java反射学习】方法的反射/成员变量的反射/构造函数的反射
- Java反射获取构造方法
- 《黑马程序员》 使用反射获取字节码文件中的方法
- 黑马程序员--03.反射--07【含有数组参数的成员方法的反射】【数组的反射】
- 黑马程序员--反射--利用反射获取方法名和字段名
- 反射_通过反射获取私有构造方法并使用
- 反射-通过反射获取无参构造方法并使用
- 反射-通过反射获取带参构造方法并使用
- 反射-通过反射获取私有构造方法并使用
- java反射---获取类的构造方法
- Java反射获取属性、方法、构造器
- 反射获取构造方法并创建对象
- JAVA 采用反射机制 获取构造方法
- 反射获取构造方法并使用
- 黑马程序员--03.反射--04【AccessibleObject类】【反射获取成员字段】
- hdu-C语言合法标识符
- 24点游戏-hero
- A、B两台电脑之间的访问问题,A、B之间不能相互访问
- MyBatis_总结文档下载
- MyEclipse Web项目修改Context Root
- 黑马程序员--03.反射--03【反射获取构造方法】
- hdu-查找最大元素
- 快速排序的python实现
- Android 屏幕适配问题
- hdu 2602 Bone Collector (01背包 )
- 各函数功能
- 安装和使用花生壳(linux)
- 每个人都用他自己的方式努力地活着
- Dom4j编写XML文件