简单尝试:

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),通过反射创建对象的更多相关文章

  1. .NET 反射(Reflection)

    这节讲一下.NET 中的一个技术:反射(Reflection). 反射是一种很重要的技术,它可以在程序运行时,动态的获取类的实例,并调用实例中的任何方法.它就像一面镜子,映射出一个类的所有细节.    ...

  2. [.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦

    [.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦 本节导读:上篇文章简单介绍了.NET面向对象中一个重要的技术反射的基本应用,它可以让我们动态的调 ...

  3. [整理]C#反射(Reflection)详解

    本人理解: 装配件:Assembly(程序集) 晚绑定:后期绑定 MSDN:反射(C# 编程指南) -----------------原文如下-------- 1. 什么是反射2. 命名空间与装配件的 ...

  4. c#之反射(Reflection)

    一.反射是什么 反射就是.Net FrameWork框架为我们提供的一个帮助类库,它可以读取我们通过编译后生成的dll和exe文件里面metadate的信息. 反射可以动态的加载dll和exe文件,动 ...

  5. C#反射(Reflection)详解

    1. 什么是反射2. 命名空间与装配件的关系3. 运行期得到类型信息有什么用4. 如何使用反射获取类型5. 如何根据类型来动态创建对象6. 如何获取方法以及动态调用方法7. 动态创建委托 1.什么是反 ...

  6. C# 反射Reflection——反射反射程序员的快乐

    一.什么是反射 反射Reflection:System.Reflection,是.Net Framework提供的一个帮助类库,可以读取并使用metadata. 反射是无处不在的,MVC-Asp.Ne ...

  7. [.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程

    [.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程 本节导读:本节主要介绍什么是.NET反射特性,.NET反射能为我们做些什么,最后介绍几种常用的 ...

  8. CSharpGL(43)环境映射(Environment Mapping)-天空盒(Skybox)反射(Reflection)和折射(Refraction)

    CSharpGL(43)环境映射(Environment Mapping)-天空盒(Skybox)反射(Reflection)和折射(Refraction) 开始 如图所示,本文围绕GLSL里的sam ...

  9. 代理(Proxy)和反射(Reflection)

    前面的话 ES5和ES6致力于为开发者提供JS已有却不可调用的功能.例如在ES5出现以前,JS环境中的对象包含许多不可枚举和不可写的属性,但开发者不能定义自己的不可枚举或不可写属性,于是ES5引入了O ...

  10. C#-反射reflection

    目录 简介 引入 1.新建类库 2. 类库的使用 3.反射 反射实例1 反射实例2 反射实例3 C# shanzm 简介 反射(reflection)是什么? 在<精通C#>中是这么说的& ...

随机推荐

  1. 初识python: 多态

    多态:允许你将父对象设置成为,与一个或更多其子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作.    简单讲就是:允许将子类类型的指针赋值给父类类型的指针. 多态 ...

  2. 初识python: 字符编码转换

    指定当前文件编码格式:#-*- coding:utf-8 -*-unicode(万国码): 英文字母 1个字节,中文3个字节python中所有的字符都是unicode编码所有非unicode编码互转都 ...

  3. 通过js触发launch事件获取页面信息

    注:图片如果损坏,点击文章链接:https://www.toutiao.com/i6814776265602499080/ 承接上一篇文档<页面Cookie的JS文件编写> 思路 继续之前 ...

  4. Enumy:一款功能强大的Linux后渗透提权枚举工具

    Enumy是一款功能强大的Linux后渗透提权枚举工具,该工具是一个速度非常快的可移植可执行文件,广大研究人员可以在针对Linux设备的渗透测试以及CTF的后渗透阶段利用该工具实现权限提升,而Enum ...

  5. MCU软件最佳实践——矩阵键盘驱动

    1.矩阵键盘vs独立按键 在mcu应用开发过程中,独立按键比较常见,但是在需要的按键数比较多时,使用矩阵键盘则可以减少io占用,提高系统资源利用率.例如,某mcu项目要求有16个按钮,如果采用独立按键 ...

  6. Ubuntu下使用VS Code创建Spring Boot工程

    目的 我们将在Ubuntu桌面系统下,使用VS Code(Visual Studio Code)编辑器从零开始创建一个Spring Boot工程,并实现一个简单的RESTful风格接口.使用这套流程的 ...

  7. Python36 使用Redis 构建分布式爬虫(未完)

    很长时间未更新了,人懒了. 最近有不少的东西,慢慢写吧,最近尝试了一下python 使用Redis 来构建分布式爬虫: 单体爬虫有很多缺点,但是在学习过程中能够学习爬虫的基本理念与运行模式,在后期构建 ...

  8. Mac中显示及隐藏文件和文件夹的方法

    一.方法一 直接在文件或文件夹名前面的加一个'.'点号,然后系统会弹出修改确认对话框,点好就行了. 隐藏文件 解除隐藏可以通过方法三显示所有隐藏文件,找到该文件去掉开头的'.',然后通过方法二来解除隐 ...

  9. Python中open函数怎么操作文件--9

    转:https://www.tuicool.com/wx/vYjaYnV 在 Python 中,如果想要操作文件,首先需要创建或者打开指定的文件,并创建一个文件对象,而这些工作可以通过内置的 open ...

  10. hadoop面试

    hadoop.apache.orgspark.apache.orgflink.apache.orghadoop :HDFS/YARN/MAPREDUCE HDFS读写流程 NameNode DataN ...