反射(reflection),通过反射创建对象
简单尝试:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; public class animal {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class name = Class.forName("com.zjl.test.reflection.cat");
Object o = name.newInstance();
Method who = name.getMethod("who");
who.invoke(o);
}
}
一、反射机制:
1.反射机制允许程序在执行期借助于Reflection
API取得任何类的内部信息(比如成员变量,构造器,成员方法等等),并能操作对象的属性及方法。反射在设计模式和框架底层都会用到
2.加载完类之后,在堆中就产生了一个Class类型
的对象(一个类只有一个Class对象),这个对象包含了类的完整结构信息。通过这个对象得到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以,形象的称之为:反射
应用实例:
获取class类的四种方法:
public class GetClass_ {
public static void main(String[] args) throws ClassNotFoundException { //1. Class.forName
String classAllPath = "com.hspedu.Car"; //通过读取配置文件获取
Class<?> cls1 = Class.forName(classAllPath);
System.out.println(cls1); //2. 类名.class , 应用场景: 用于参数传递
Class cls2 = Car.class;
System.out.println(cls2); //3. 对象.getClass(), 应用场景,有对象实例
Car car = new Car();
Class cls3 = car.getClass();
System.out.println(cls3); //4. 通过类加载器【4种】来获取到类的Class对象
//(1)先得到类加载器 car
ClassLoader classLoader = car.getClass().getClassLoader();
//(2)通过类加载器得到Class对象
Class cls4 = classLoader.loadClass(classAllPath);
System.out.println(cls4); //cls1 , cls2 , cls3 , cls4 其实是同一个对象
System.out.println(cls1.hashCode());
System.out.println(cls2.hashCode());
System.out.println(cls3.hashCode());
System.out.println(cls4.hashCode()); //5. 基本数据(int, char,boolean,float,double,byte,long,short) 按如下方式得到Class类对象
Class<Integer> integerClass = int.class;
Class<Character> characterClass = char.class;
Class<Boolean> booleanClass = boolean.class;
System.out.println(integerClass);//int //6. 基本数据类型对应的包装类,可以通过 .TYPE 得到Class类对象
Class<Integer> type1 = Integer.TYPE;
Class<Character> type2 = Character.TYPE; //其它包装类BOOLEAN, DOUBLE, LONG,BYTE等待
System.out.println(type1); //两个类型是相同的:
System.out.println(integerClass.hashCode());//?
System.out.println(type1.hashCode());//? }
}
二、类加载
基本说明:
反射机制是java实现动态语言的关键,也就是通过反射实现类动态加载。
1.静态加载:编译时加载相关的类,如果没有则报错,依赖性太强
2动态加载:运行时加载需要的类,如果运行时不用该类,则不报错,降低了依赖性
3.举例说明
类加载时机:
1.当创建对象时(new) //静态加载
2.当子类被加载时,父类也加载 //静态加载
3.调用类中的静态成员时 //静态加载
4.通过反射 //动态加载
类加载:
类加载各阶段完成任务:
加载阶段:
JVM在该阶段的主要目的是将字节码从不同的数据源(可能是 class 文件、也可能是jar包,甚至网络)转化为二进制字节流加载到内存中,并生成一个代表该类的
java.lang.Class对象
连接阶段-验证:
连接阶段-准备:
变量的准备简介:
连接阶段-解析:
1.虚拟机将常量池内的符号引用替换为直接引用的过程。
初始化(Initiaalization):
1.到初始化阶段,才真正开始执行类中定义的Java程序代码,此阶段是执行
<clinit>0方法的过程。
2.<clinit>()方法是由编译器按语句在源文件中出现的顺序,依次自动收集类中的所有
静态变量的赋值动作和静态代码块中的语句,并进行合并。
3.虚拟机会保证一个类的<clinit>()方法在多线程环境中被正确地加锁、同步,如果
多个线程同时去初始化一个类,那么只会有一个线程去执行这个类的<clinit>()方法,其他线程都需要阻塞等待,直到活动线程执行<clinit>()方法完毕[debug源码]
通过反射获取类的结构信息:
java.lang.class类:
1. getName:获取全类名
2. getSimpleName:获取简单类名
3. getFields:获取所有public修饰的属性,包含本类以及父类的
4. getDeclaredFields:获取本类中所有属性
5. getMethods:获取所有public修饰的方法,包含本类以及父类的
6. getDeclaredMethods:获取本类中所有方法
7. getConstructors: 获取所有public修饰的构造器,本类
8. getDeclaredConstructors:获取本类中所有构造器
9. getPackage:以Package形式返回包信息
10.getSuperClass:以Class形式返回父类信息
11.getlnterfaces:以Class[形式返回接口信息
12.getAnnotations:以Annotation[]形式返回注解信息
java.lang.reflect.Field类:
1. getModifiers:以int形式返回修饰符
[说明:默认修饰符是0,public是1,private是2,protected是4,static是8,final是16], public(1) + static (8) = 9
2.getType:以Class形式返回类型
3.getName:返回属性名
java.lang.reflect.Method类:
1.getModifiers:以int形式返回修饰符
[说明:默认修饰符是0,public 是1,private是2,protected是4,static是8,final是16]
2.getReturnType:以Class形式获取返回类型
3.getName:返回方法名
4. getParameterTypes:以Class[返回参数类型数组
java.lang.reflect.Constructor类:
1.getModifiers: 以int形式返回修饰符
2.getName:返回构造器名(全类名)
3.getParameterTypes:以Class[]返回参数类型数组
三、通过反射实现类加载:
访问构造器:
1、方法一:调用类中的public修饰的无参构造器
2、方式二:调用类中指定构造器
3. Class类相关方法
newlnstance:调用类中的无参构造器,获取对应类的对象
getConstructor(Class...clazz):根据参数列表,获取对应的public构造器对象getDecalaredConstructor(Class...clazz):根据参数列表,获取对应的所有构造器对象
4. Constructor类相关方法
setAccessible:暴破
newlnstance(Object...obj):调用构造器
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; public class ReflectCreateInstance {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
//1、获取User的class对象
Class<?> aClass = Class.forName("com.zjl.test.reflection.User");
//2、通过public的无参构造器创建实例
Object o = aClass.newInstance();
System.out.println(o);
//3、通过public的有参构造器创建实例
//得到构造器对象
Constructor<?> constructor = aClass.getConstructor(String.class);
//创建实例,并传入参数
Object who = constructor.newInstance("who");
System.out.println(who);
//4.通过非public的有参构造器创建实例
//得到一个private的构造器对象
Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(int.class, String.class);
//对该构造器进行暴破,使得可以通过反射语句访问private的构造器,方法,属性
declaredConstructor.setAccessible(true);
//创建一个private对象的实例并赋值
Object o1 = declaredConstructor.newInstance(20, "Where");
System.out.println(o1);
}
}
class User{
private int age = 10;
private String name = "hello"; public User(){ } public User(String name) {
this.name = name;
} private User(int age, String name) {
this.age = age;
this.name = name;
} @Override
public String toString() {
return "User{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
访问类中的属性成员:
1.根据属性名获取Field对象
Field f =clazz对象.getDeclaredField(属性名);
2.暴破:f.setAccessible(true);1/f 是Field
3.访问
f.set(o,值);1/ o表示对象
syso(f.get(o))://o表示对象
4.注意:如果是静态属性,则set和get中的参数o,可以写成null
通过反射访问类中的方法成员:
1.根据方法名和参数列表获取Method方法对象:Method m =
clazz.getDeclaredMethod(方法名,XX.class);
2.获取对象:Object o=clazz.newlnstance);
3.暴破:m.setAccessible(true);
4.访问:Object returnValue = m.invoke(o,实参列表);
5.注意:如果是静态方法,则invoke的参数o,可以写成null!
反射(reflection),通过反射创建对象的更多相关文章
- .NET 反射(Reflection)
这节讲一下.NET 中的一个技术:反射(Reflection). 反射是一种很重要的技术,它可以在程序运行时,动态的获取类的实例,并调用实例中的任何方法.它就像一面镜子,映射出一个类的所有细节. ...
- [.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦
[.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦 本节导读:上篇文章简单介绍了.NET面向对象中一个重要的技术反射的基本应用,它可以让我们动态的调 ...
- [整理]C#反射(Reflection)详解
本人理解: 装配件:Assembly(程序集) 晚绑定:后期绑定 MSDN:反射(C# 编程指南) -----------------原文如下-------- 1. 什么是反射2. 命名空间与装配件的 ...
- c#之反射(Reflection)
一.反射是什么 反射就是.Net FrameWork框架为我们提供的一个帮助类库,它可以读取我们通过编译后生成的dll和exe文件里面metadate的信息. 反射可以动态的加载dll和exe文件,动 ...
- C#反射(Reflection)详解
1. 什么是反射2. 命名空间与装配件的关系3. 运行期得到类型信息有什么用4. 如何使用反射获取类型5. 如何根据类型来动态创建对象6. 如何获取方法以及动态调用方法7. 动态创建委托 1.什么是反 ...
- C# 反射Reflection——反射反射程序员的快乐
一.什么是反射 反射Reflection:System.Reflection,是.Net Framework提供的一个帮助类库,可以读取并使用metadata. 反射是无处不在的,MVC-Asp.Ne ...
- [.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程
[.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程 本节导读:本节主要介绍什么是.NET反射特性,.NET反射能为我们做些什么,最后介绍几种常用的 ...
- CSharpGL(43)环境映射(Environment Mapping)-天空盒(Skybox)反射(Reflection)和折射(Refraction)
CSharpGL(43)环境映射(Environment Mapping)-天空盒(Skybox)反射(Reflection)和折射(Refraction) 开始 如图所示,本文围绕GLSL里的sam ...
- 代理(Proxy)和反射(Reflection)
前面的话 ES5和ES6致力于为开发者提供JS已有却不可调用的功能.例如在ES5出现以前,JS环境中的对象包含许多不可枚举和不可写的属性,但开发者不能定义自己的不可枚举或不可写属性,于是ES5引入了O ...
- C#-反射reflection
目录 简介 引入 1.新建类库 2. 类库的使用 3.反射 反射实例1 反射实例2 反射实例3 C# shanzm 简介 反射(reflection)是什么? 在<精通C#>中是这么说的& ...
随机推荐
- 初识python: 多态
多态:允许你将父对象设置成为,与一个或更多其子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作. 简单讲就是:允许将子类类型的指针赋值给父类类型的指针. 多态 ...
- 初识python: 字符编码转换
指定当前文件编码格式:#-*- coding:utf-8 -*-unicode(万国码): 英文字母 1个字节,中文3个字节python中所有的字符都是unicode编码所有非unicode编码互转都 ...
- 通过js触发launch事件获取页面信息
注:图片如果损坏,点击文章链接:https://www.toutiao.com/i6814776265602499080/ 承接上一篇文档<页面Cookie的JS文件编写> 思路 继续之前 ...
- Enumy:一款功能强大的Linux后渗透提权枚举工具
Enumy是一款功能强大的Linux后渗透提权枚举工具,该工具是一个速度非常快的可移植可执行文件,广大研究人员可以在针对Linux设备的渗透测试以及CTF的后渗透阶段利用该工具实现权限提升,而Enum ...
- MCU软件最佳实践——矩阵键盘驱动
1.矩阵键盘vs独立按键 在mcu应用开发过程中,独立按键比较常见,但是在需要的按键数比较多时,使用矩阵键盘则可以减少io占用,提高系统资源利用率.例如,某mcu项目要求有16个按钮,如果采用独立按键 ...
- Ubuntu下使用VS Code创建Spring Boot工程
目的 我们将在Ubuntu桌面系统下,使用VS Code(Visual Studio Code)编辑器从零开始创建一个Spring Boot工程,并实现一个简单的RESTful风格接口.使用这套流程的 ...
- Python36 使用Redis 构建分布式爬虫(未完)
很长时间未更新了,人懒了. 最近有不少的东西,慢慢写吧,最近尝试了一下python 使用Redis 来构建分布式爬虫: 单体爬虫有很多缺点,但是在学习过程中能够学习爬虫的基本理念与运行模式,在后期构建 ...
- Mac中显示及隐藏文件和文件夹的方法
一.方法一 直接在文件或文件夹名前面的加一个'.'点号,然后系统会弹出修改确认对话框,点好就行了. 隐藏文件 解除隐藏可以通过方法三显示所有隐藏文件,找到该文件去掉开头的'.',然后通过方法二来解除隐 ...
- Python中open函数怎么操作文件--9
转:https://www.tuicool.com/wx/vYjaYnV 在 Python 中,如果想要操作文件,首先需要创建或者打开指定的文件,并创建一个文件对象,而这些工作可以通过内置的 open ...
- hadoop面试
hadoop.apache.orgspark.apache.orgflink.apache.orghadoop :HDFS/YARN/MAPREDUCE HDFS读写流程 NameNode DataN ...