java 基础之--反射详解
java 反射绝大部分都位于 java.lang.reflect package 中;常用的类就是:
1.class类:代表一个类 2.field类:代表类的成员变量 3.method:代表类的方法 4.constructor:代表类的构造方法 5.array:提供动态创建数组,访问数组元素的静态方法
在Java 中无论生成这个类的多少个对象,这个对象都对应同一个class 对象
Class 对象生成的三种方式:
1.使用class类的静态方法。Class.forNanme("packageName"); ---> Class<?> forName =Class.forName("com.project.Test")获取Test类的class 对象;
2.类名.class ;---> Class<?> clazz =Test.class;
3.对象.class();--->Test te =new Test(); te.getClass(); Class<?> clazz = te.getClass();
使用反射进行方法的调用:
1.获取class对象
2.通过getMethod method obtain specific Method 参数传入(1.方法名,2.方法传入的参数class 类型)
3.获取类的实例
4.调用方法的invoke method 。参数传入(1.类的实例,2.具体方法传入的参数)
This is Example
public class Reflect2 { public static void main(String[] args) throws Exception { //judge memory
Class<?> forName = Class.forName("com.java.baseknowledge.reflect.TheReflect");
System.out.println(forName==TheReflect.class);
// get method ,accept method name and class of param
Method method = forName.getMethod("add", Integer.class,Integer.class);
//instance of object
Object newInstance = forName.newInstance();
//method invoke,accept instance of object and method param
System.out.println(method.invoke(newInstance, 4,5)); } } class TheReflect{ private String name;
private Integer age;
public Integer add(Integer param1,Integer param2) { return param1+param2; } public void sayHello(String param1) { System.out.println("Hello"+param1);
} }
反射通过构造函数的方式进行创建对象的两种方式
1.obtain class object use generation class object method 2.通过class对象的.getConstructor(class对象) 方法 obtain specific Constructor 3.通过Constructor 类中的 newInstance(object obj) 方法获取类的实例 而,对于空参数的构造函数对象的创建,我们直接使用
class对象的.newInstance(),就可以创建一个对象,只适用于构造空的构造函数
please fllow me next example
this is Example
public class ReflectConstructor { public static void main(String[] args) throws Exception { Class<?> name = Class.forName("com.java.baseknowledge.reflect.TheReflect01"); //obtain constructor
Constructor<?>[] constructors = name.getConstructors(); for(int i=0;i<constructors.length;i++) { //print all constructors
System.out.println(constructors[i]); } //无参构造函数实例创建,direct class object .newInstance
Object newInstance2 = name.newInstance();
//有参构造函数执行
Constructor<?> constructor = name.getConstructor(String.class,Integer.class); TheReflect01 newInstance = (TheReflect01)constructor.newInstance("cys",56); } } class TheReflect01{ public TheReflect01() {
System.out.println("no param constructor execute");
}
public TheReflect01(String name,Integer age) {
this.name=name;
this.age=age;
System.out.println("有参数构造函数块执行"+name+"...."+age);
}
private String name;
private Integer age;
public Integer add(Integer param1,Integer param2) { return param1+param2; } public void sayHello(String param1) { System.out.println("Hello"+param1);
} }
Java 反射如何调用私有的方法与成员变量呢?
1.class 方法中找到带有declared字样的方法基本上都是可以返回所有的成员变量与方法的,不管是private 还是protect ;
2.设置setAccessible(true) 可以压制Java 对特殊修饰符的检查,我们就可以在反射中调用private 方法; Fllow next Example
package com.java.baseknowledge.reflect; import java.lang.reflect.Field;
import java.lang.reflect.Method; /**
* invocation private method and private property use reflect
* @author iscys
*
*/
public class InvocationPrivate { public static void main(String[] args) throws Exception { Class<?> forName = Class.forName("com.java.baseknowledge.reflect.primitive01"); //obtain private method
Method declaredMethod = forName.getDeclaredMethod("TestReflect", new Class[] {String.class,String.class}); //instance of object
Object newInstance = forName.newInstance(); //set accessiable,suppress Java language access check,压制Java 语法检查,就可以进行调用private 方法了 declaredMethod.setAccessible(true); //invoke method declaredMethod.invoke(newInstance, "test01","test02"); System.out.println("....private field ");
//invoke private property
Field declaredField = forName.getDeclaredField("name");
declaredField.setAccessible(true);
declaredField.set(newInstance, "iscys");
Object object = declaredField.get(newInstance);
System.out.println(object); } } /**
* defined private method
* @author iscys
*
*/
class primitive01{ private String name; private void TestReflect(String param,String param1) { System.out.println("this invoke private methood start.."+param+".."+param1); } }
java 基础之--反射详解的更多相关文章
- Java基础之 数组详解
前言:Java内功心法之数组详解,看完这篇你向Java大神的路上又迈出了一步(有什么问题或者需要资料可以联系我的扣扣:734999078) 数组概念 同一种类型数据的集合.其实数组就是一个容器. 数组 ...
- java基础之:详解内部类(转载)
可以将一个类的定义放在另一个类的定义内部,这就是内部类. 内部类是一个非常有用的特性但又比较难理解使用的特性(鄙人到现在都没有怎么使用过内部类,对内部类也只是略知一二). 第一次见面 内部类我们从外面 ...
- java基础-泛型举例详解
泛型 泛型是JDK5.0增加的新特性,泛型的本质是参数化类型,即所操作的数据类型被指定为一个参数.这种类型参数可以在类.接口.和方法的创建中,分别被称为泛型类.泛型接口.泛型方法. 一.认识泛型 在没 ...
- Java基础知识面试题详解(2019年)
文章目录 1. 面向对象和面向过程的区别 2. Java 语言有哪些特点? 3. 关于 JVM JDK 和 JRE 最详细通俗的解答 JVM JDK 和 JRE 4. Oracle JDK 和 Ope ...
- Java基础(52):ClassCastException详解(转)
ClassCastException,从字面上看,是类型转换错误,通常是进行强制类型转换时候出的错误.下面对产生ClassCastException异常的原因进行分析,然后给出这种异常的解决方法. 这 ...
- java基础(十四)-----详解匿名内部类——Java高级开发必须懂的
在这篇博客中你可以了解到匿名内部类的使用.匿名内部类要注意的事项.匿名内部类使用的形参为何要为final. 使用匿名内部类内部类 匿名内部类由于没有名字,所以它的创建方式有点儿奇怪.创建格式如下: n ...
- Java基础之数组详解
数组对于每一门编程语言来说都是重要的数据结构之一,当然不同语言对数组的实现及处理也不尽相同. Java 语言中提供的数组是用来存储固定大小的同类型元素. 你可以声明一个数组变量,如 numbers[1 ...
- java基础篇---枚举详解
在JDK1.5之前,JAVA可以有两种方式定义新类型:类和接口,对于大部分面向对象编程,有这两种似乎就足够了,但是在一些特殊情况就不合适.例如:想要定义一个Color类,它只能有Red,Green,B ...
- Java基础 面向对象的详解
1.1 万物皆对象 我们是怎么认识世界的? 人类从小就不断的接触到各种各类存在世界上的各种生物,然后通过事物的公共特性,将它们归类,所以以后就不会出现见到猫叫老虎.那么我们在现实生活中,是通过具体的某 ...
随机推荐
- leetcode 题解: Gray Code
第一眼看到就是枚举,回溯法. n位的ans就是在n-1的ans的基础上,每一个在首位加上1. 但是有个难点,要保证相邻两数之间只有一位在变化,怎么办? 首先 00 00 01 00 01 11 10 ...
- PHP常量总结
概念 常量我们可以理解为值不变的量.常量只要被定义了,在程序脚本的其他任何地方都不能改变. 因为常量被定义后不能被修改,所以即使重定义常量的值,常量的值也是第一次定义常量时的值 常量不管在哪里被定义, ...
- Zookeeper 在Linux系统的安装
注册中心Zookeeper 官方推荐使用 zookeeper 注册中心.注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小. Z ...
- linux内核中的const成员是否可以修改?
本文的基础知识:由于前半部分内容是转的,且不知道原文出处,没法给出原文地址,大家自行百度 const的实现机制 const究竟是如何实现的呢?对于声明为const的内置类型,例如int,short,l ...
- 讲一讲Servlet的生命周期
1 实例化 servlet 容器创建servlet的实例; 2初始化 该容器调用init()方法; 每个实例,init()方法只被调用一次 3 服务 如果请求Servlet,则容器 ...
- [jQ/PHP]使用JS数组储值的两种情况(提交PHP处理)
---------------------------------------------------------------------------------------------------- ...
- C# 图像处理:获取鼠标位置信息(全局)
Point ms = Control.MousePosition; //获取鼠标位置 this.label2.Text = string.Format("{0}:{1}", ms. ...
- C++ 学习 之Struct
转自https://blog.csdn.net/bestconvenient/article/details/30734139 最开始,就让我们来讨论一下一个最最基本,也最最容易被人忽视掉的问题——C ...
- 吴裕雄 08-MySQL创建数据表
MySQL 创建数据表创建MySQL数据表需要以下信息:表名表字段名定义每个表字段 语法以下为创建MySQL数据表的SQL通用语法:CREATE TABLE table_name (column_na ...
- 了解一些dos常用命令
备注:[] ——可选项 <>——必填项 DOS 特殊命令应用技巧: 向上箭头“↑”和向下箭头“↓”——回看上一次执行的命令 "Ctrl+C"组合——中断操作 在命令 ...