33反射类加载反射讲义.docx

上传人:b****2 文档编号:20134416 上传时间:2023-04-25 格式:DOCX 页数:25 大小:23.03KB
下载 相关 举报
33反射类加载反射讲义.docx_第1页
第1页 / 共25页
33反射类加载反射讲义.docx_第2页
第2页 / 共25页
33反射类加载反射讲义.docx_第3页
第3页 / 共25页
33反射类加载反射讲义.docx_第4页
第4页 / 共25页
33反射类加载反射讲义.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

33反射类加载反射讲义.docx

《33反射类加载反射讲义.docx》由会员分享,可在线阅读,更多相关《33反射类加载反射讲义.docx(25页珍藏版)》请在冰豆网上搜索。

33反射类加载反射讲义.docx

33反射类加载反射讲义

第33天反射

今日内容介绍

◆类加载器

◆反射构造方法

◆反射成员变量

◆反射成员方法

◆反射配置文件运行类中的方法

第1章类加载器

1.1类的加载

当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。

●加载

就是指将class文件读入内存,并为之创建一个Class对象。

任何类被使用时系统都会建立一个Class对象

●连接

验证是否有正确的内部结构,并和其他类协调一致

准备负责为类的静态成员分配内存,并设置默认初始化值

解析将类的二进制数据中的符号引用替换为直接引用

●初始化

就是我们以前讲过的初始化步骤

1.2类初始化时机

1.创建类的实例

2.类的静态变量,或者为静态变量赋值

3.类的静态方法

4.使用反射方式来强制创建某个类或接口对应的java.lang.Class对象

5.初始化某个类的子类

6.直接使用java.exe命令来运行某个主类

1.3类加载器

●负责将.class文件加载到内在中,并为之生成对应的Class对象。

●虽然我们不需要关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行

1.4类加载器的组成

●BootstrapClassLoader根类加载器

也被称为引导类加载器,负责Java核心类的加载

比如System,String等。

在JDK中JRE的lib目录下rt.jar文件中

●ExtensionClassLoader扩展类加载器

负责JRE的扩展目录中jar包的加载。

在JDK中JRE的lib目录下ext目录

●SystemClassLoader系统类加载器

负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径。

通过这些描述就可以知道我们常用的类,都是由谁来加载完成的。

到目前为止我们已经知道把class文件加载到内存了,那么,如果我们仅仅站在这些class文件的角度,我们如何来使用这些class文件中的内容呢?

这就是我们反射要研究的内容。

第2章反射

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

要想解剖一个类,必须先要获取到该类的字节码文件对象。

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

2.1Class类

阅读API的Class类得知,Class没有公共构造方法。

Class对象是在加载类时由Java虚拟机以及通过调用类加载器中的defineClass方法自动构造的

●获取Class对象的三种方式

方式一:

通过Object类中的getObject()方法

Personp=newPerson();

Classc=p.getClass();

方式二:

通过类名.class获取到字节码文件对象(任意数据类型都具备一个class静态属性,看上去要比第一种方式简单)。

Classc2=Person.class;

方式三:

通过Class类中的方法(将类名作为字符串传递给Class类中的静态方法forName即可)。

Classc3=Class.forName("Person");

●注意:

第三种和前两种的区别

前两种你必须明确Person类型.

后面是指定这种类型的字符串就行.这种扩展更强.我不需要知道你的类.我只提供字符串,按照配置文件加载就可以了

●代码演示

/*

*获取.class字节码文件对象的方式

*1:

通过Object类中的getObject()方法

*2:

通过类名.class获取到字节码文件对象

*3:

反射中的方法,

*publicstaticClass

>forName(StringclassName)throwsClassNotFoundException

*返回与带有给定字符串名的类或接口相关联的Class对象

*/

publicclassReflectDemo{

publicstaticvoidmain(String[]args)throwsClassNotFoundException{

//1:

通过Object类中的getObject()方法

//Personp1=newPerson();

//Classc1=p1.getClass();

//System.out.println("c1="+c1);

//2:

通过类名.class获取到字节码文件对象

//Classc2=Person.class;

//System.out.println("c2="+c2);

//3:

反射中的方法

Classc3=Class.forName("cn.itcast_01_Reflect.Person");//包名.类名

System.out.println("c3="+c3);

}

}

●Person类

packagecn.itcast_01_Reflect;

publicclassPerson{

//成员变量

publicStringname;

publicintage;

privateStringaddress;

//构造方法

publicPerson(){

System.out.println("空参数构造方法");

}

publicPerson(Stringname){

this.name=name;

System.out.println("带有String的构造方法");

}

//私有的构造方法

privatePerson(Stringname,intage){

this.name=name;

this.age=age;

System.out.println("带有String,int的构造方法");

}

publicPerson(Stringname,intage,Stringaddress){

this.name=name;

this.age=age;

this.address=address;

System.out.println("带有String,int,String的构造方法");

}

//成员方法

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

publicvoidmethod1(){

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

}

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

publicvoidmethod2(Stringname){

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

}

//有返回值,没有参数

publicintmethod3(){

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

return123;

}

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

publicStringmethod4(Stringname){

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

return"哈哈"+name;

}

//私有方法

privatevoidmethod5(){

System.out.println("私有方法");

}

@Override

publicStringtoString(){

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

}

}

2.2通过反射获取构造方法并使用

在反射机制中,把类中的成员(构造方法、成员方法、成员变量)都封装成了对应的类进行表示。

其中,构造方法使用类Constructor表示。

可通过Class类中提供的方法获取构造方法:

●返回一个构造方法

⏹publicConstructorgetConstructor(Class

>...parameterTypes)获取public修饰,指定参数类型所对应的构造方法

⏹publicConstructorgetDeclaredConstructor(Class

>...parameterTypes)获取指定参数类型所对应的构造方法(包含私有的)

●返回多个构造方法

⏹publicConstructor

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

⏹publicConstructor

>[]getDeclaredConstructors()获取所有的构造方法(包含私有的)

●获取构造方法的代码演示:

publicclassReflectDemo{

publicstaticvoidmain(String[]args)throwsClassNotFoundException,NoSuchMethodException,SecurityException{

//获取Class对象

Classc=Class.forName("cn.itcast_01_Reflect.Person");//包名.类名

//获取所有的构造方法

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

Constructor[]cons=c.getDeclaredConstructors();

for(Constructorcon:

cons){

System.out.println(con);

}

System.out.println("------------------------");

//获取一个构造方法

//publicPerson()

Constructorcon1=c.getConstructor(null);

System.out.println(con1);

//publicPerson(Stringname)

Constructorcon2=c.getConstructor(String.class);

System.out.println(con2);

//privatePerson(Stringname,intage)

Constructorcon3=c.getDeclaredConstructor(String.class,int.class);

System.out.println(con3);

//publicPerson(Stringname,intage,Stringaddress)

Constructorcon4=c.getDeclaredConstructor(String.class,int.class,String.class);

System.out.println(con4);

}

}

2.2.1通过反射方式,获取构造方法,创建对象

获取构造方法,步骤如下:

1.获取到Class对象

2.获取指定的构造方法

3.通过构造方法类Constructor中的方法,创建对象

publicTnewInstance(Object...initargs)

●代码演示

publicclassConstructorDemo{

publicstaticvoidmain(String[]args)throwsClassNotFoundException,NoSuchMethodException,SecurityException,InstantiationException,IllegalAccessException,IllegalArgumentException,InvocationTargetException{

//1,获取到Class对象

Classc=Class.forName("cn.itcast_01_Reflect.Person");//包名.类名

//2,获取指定的构造方法

//publicPerson()

//Constructorcon=c.getConstructor(null);

//publicPerson(Stringname,intage,Stringaddress)

Constructorcon=c.getConstructor(String.class,int.class,String.class);

//3,通过构造方法类中Constructor的方法,创建对象

//Objectobj=con.newInstance(null);

Objectobj=con.newInstance("小明",22,"哈尔滨");

//显示

System.out.println(obj);

}

}

2.2.2通过反射方式,获取私有构造方法,创建对象

AccessibleObject类是Field、Method和Constructor对象的父类。

它提供了将反射的对象标记为在使用时取消默认Java语言访问控制检查的能力。

对于公共成员、默认(打包)访问成员、受保护成员和私有成员,在分别使用Field、Method或Constructor对象来设置或获取字段、调用方法,或者创建和初始化类的新实例的时候,会执行访问检查。

常用方法如下:

●publicvoidsetAccessible(boolean flag)throwsSecurityException

参数值为true则指示反射的对象在使用时应该取消Java语言访问检查。

参数值为false则指示反射的对象应该实施Java语言访问检查。

获取私有构造方法,步骤如下:

1.获取到Class对象

2.获取指定的构造方法

3.暴力访问,通过setAccessible(boolean flag)方法

4.通过构造方法类Constructor中的方法,创建对象

publicTnewInstance(Object...initargs)

●代码演示:

publicclassConstructorDemo2{

publicstaticvoidmain(String[]args)throwsClassNotFoundException,NoSuchMethodException,SecurityException,InstantiationException,IllegalAccessException,IllegalArgumentException,InvocationTargetException{

//1,获取到Class对象

Classc=Class.forName("cn.itcast_01_Reflect.Person");//包名.类名

//2,获取指定的构造方法

//privatePerson(Stringname,intage)

Constructorcon=c.getDeclaredConstructor(String.class,int.class);

//3,暴力反射

con.setAccessible(true);//取消Java语言访问检查

//4,通过构造方法类中的功能,创建对象

Objectobj=con.newInstance("小明",23);

System.out.println(obj);

}

}

2.3通过反射获取成员变量并使用

在反射机制中,把类中的成员变量使用类Field表示。

可通过Class类中提供的方法获取成员变量:

●返回一个成员变量

⏹publicFieldgetField(Stringname)获取指定的public修饰的变量

⏹publicFieldgetDeclaredField(Stringname)获取指定的任意变量

●返回多个成员变量

⏹publicField[]getFields()获取所有public修饰的变量

⏹publicField[]getDeclaredFields()获取所有的变量(包含私有)

●获取成员变量的代码演示:

publicclassFieldDemo{

publicstaticvoidmain(String[]args)throwsClassNotFoundException,NoSuchFieldException,SecurityException{

//获取Class对象

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

//获取成员变量

//多个变量

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

Field[]fields=c.getDeclaredFields();

for(Fieldfield:

fields){

System.out.println(field);

}

System.out.println("-----------------");

//一个变量

//publicintage;

FieldageField=c.getField("age");

System.out.println(ageField);

//privateStringaddress

FieldaddressField=c.getDeclaredField("address");

System.out.println(addressField);

}

}

2.3.1通过反射,创建对象,获取指定的成员变量,进行赋值与获取值操作

获取成员变量,步骤如下:

1.获取Class对象

2.获取构造方法

3.通过构造方法,创建对象

4.获取指定的成员变量(私有成员变量,通过setAccessible(boolean flag)方法暴力访问)

5.通过方法,给指定对象的指定成员变量赋值或者获取值

◆publicvoidset(Objectobj,Objectvalue)

在指定对象obj中,将此Field对象表示的成员变量设置为指定的新值

◆publicObjectget(Objectobj)

返回指定对象obj中,此Field对象表示的成员变量的值

●代码演示:

publicclassFieldDemo2{

publicstaticvoidmain(String[]args)throwsClassNotFoundException,NoSuchMethodException,SecurityException,InstantiationException,IllegalAccessException,IllegalArgumentException,InvocationTargetException,NoSuchFieldException{

//1,获取Class对象

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

//2,获取构造方法

//publicPerson(Stringname)

Constructorcon=c.getConstructor(String.class);

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

Objectobj=con.newInstance("小明");

//4,获取指定的成员变量

//publicStringname;

FieldnameField=c.getField("name");

//publicintage;

FieldageField=c.getField("age");

//privateStringaddress;

FieldaddressField=c.getDeclaredField("address");

addressField.setAccessible(true);//取消Java语言访问检查

//5,通过方法,给指定对象的指定成员变量赋值或者获取值

System.out.println("name="+nameField.get(obj));

System.out.println("age="+ageField.get(obj));

System.out.println("address="+addressField.get(obj));

//赋值

ageField.set(obj,23);

addressField.set(obj,"凯利广场");

System.out.println("------------------------");

System.out.println("name="+nameField.get(obj));

System.out.println("age="+ageField.get(obj));

System.out.println("address="+addressField.get(obj));

}

}

2.4通过反射获取成员方法并使用

在反射机制中,把类中的成员方法使用类Method表示。

可通过Class类中提供的方法获取成员方法:

●返回获取一个方法:

⏹publicMethodgetMethod(Stringname,Class

>...parameterTypes)

获取public修饰的方法

⏹publicMethodgetDeclaredMethod(Stringname,Class

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 其它模板

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1