java(19) - 反射机制
一.反射:
反射机制就是java程序在运行时拥有自观能力,能知晓类中的所有属性和方法。
通过反射能得到类中的任何属性和方法,也就是说反射可以打破类的封装特性,可以通过反射来调用私有方法。
让我们看个小例子:
public class Test {public static void main(String[] args) throws Exception {Class<?> classType = MethodTest.class;Method[] method = classType.getDeclaredMethods();for(Method m :method){System.out.println(m);}}
}
public class MethodTest extends MethodTest2 {public MethodTest(){}public void methodOne(){}private void methodTwo(){}private String methodThree(){return null; }public int methodFour(){return 0;}}
打印:
public void Reflection3.MethodTest.methodOne()
private void Reflection3.MethodTest.methodTwo()
private java.lang.String Reflection3.MethodTest.methodThree()
public int Reflection3.MethodTest.methodFour()
这个小例子为我们显示MethodTest类中的所有方法,其中包括了私有方法和普通方法。要想使用反射就必须获得待处理类的class对象。
除了我上面MethodTest.class获取Class对象的方法还有两种,加上我用的一共三种方式:
1).使用Class类的静态方法forName:Class.forName("java.lang.String");
例子:
public>
会打印出String中的所有方法。
2).就是使用我第一个例子中的方法。类.class的方法。
3).使用对象的getClass()方法。
例子:
public class Test {public static void main(String[] args) throws Exception {String str = "abc";Class<?> classType = str.getClass();Method[] method = classType.getDeclaredMethods();for(Method m :method){System.out.println(m);}}
}
这个将会打印出String类中所有的方法。
如何通过反射使用类中的public类型方法:
public class Test {public int sum(int a,int b){return a + b;}public String Course(String str){return "课程名:" + str;}public static void main(String[] args) throws Exception{Class<?> classType = Test.class;//通过classType.newInstance()来返回Test的实例对象,只能调用无参构造。Object obj = classType.newInstance();//第一个参数指定类中的方法名称,第二个参数指定其方法的参数类型,为什么会有第二个参数,因为类中会有重载的方法,用此来进行区分。Method sumMethod = classType.getMethod("sum",int.class,int.class);Object sum = sumMethod.invoke(obj,1,2);System.out.println((Integer)sum);System.out.println("==========================================");Method courseMethod = classType.getMethod("Course",String.class);Object course = courseMethod.invoke(obj,"Java");System.out.println(course);}}
打印:
3
==========================================
课程名:Java
上面的例子中通过classType.newInstance()来获得Test的实例,但是这个方法只能调用无参的构造方法。使用方法时用通过invoke(传入方法存在类的实例,传入方法的参数)。
有参的构造方法使用格式:先获得Class对象,然后通过该对象获得相应的Constructor对象,再通过该Constructor对象的newInstance()方法生成。
如果想通过类的带参构造方法生成对象,只能使用下面例子中的格式。
例子:
public class Test {public static void main(String[] args) throws Exception {Class<?> classType = People.class;/** Constructor con = classType.getConstructor(new Class[]{});* Object obj = con.newInstance(new Object[]{});* 也可以创建不带参数的对象。*/Constructor con = classType.getConstructor(String.class);Object obj = con.newInstance("zhangsan");System.out.println(obj);}
}
class People {private String name;public People(){}public People(String name){this.name = name;}public String getName(){return name;}
}
如何通过反射使用类中的属性和方法:
例子:
public class ReflectionTest {//执行对一个对象的copy操作。public Object copy(Object o) throws Exception{Class<?> cs = Student.class;Object obj = cs.getConstructor(new Class[]{}).newInstance(new Object[]{});Field[] field = cs.getDeclaredFields();for(Field f:field){String name = f.getName();String firstLetter = name.substring(0,1).toUpperCase();//获得对应属性的set和get方法的字符串。String getMethodName = "get"+firstLetter+name.substring(1);String setMethodName = "set"+firstLetter+name.substring(1);//获得对应属性的set和get方法。Method getMethod = cs.getMethod(getMethodName,new Class[]{});Method setMethod = cs.getMethod(setMethodName,new Class[]{f.getType()});//获得属性的返回值。Object value = getMethod.invoke(o,new Object[]{});//添加到要返回的对象中去。setMethod.invoke(obj,new Object[]{value});} return obj;
}public static void main(String[] args) throws Exception{Student t = new Student("zhangsan",1,2);ReflectionTest r = new ReflectionTest();Student s = (Student)r.copy(t);System.out.println(s.getAge()+" "+s.getName()+" "+s.getNumber());}
}
class Student {public String name;private int number;public int age;public Student(){}public Student(String name,int age,int number){this.age = age;this.name = name;this.number = number;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getNumber() {return number;}public void setNumber(int number) {this.number = number;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
反射应用于数组:
例子:
public class Test {public static void main(String[] args) throws Exception {Class<?> classType = Class.forName("java.lang.String");//第一个参数设置数组的类型,第二个设置数组的大小。Object array = Array.newInstance(classType,10);//第一个参数目标数组,第二个参数指定存放位置,第三个参数要存入的元素。Array.set(array,5,"java");//打印System.out.println((String)Array.get(array,5));}
}
打印: java
对于多维数组的创建:
例子:
public class Test {public static void main(String[] args) throws Exception {//Integer.TYPE返回原生数据类型,Integer.class返回类的类型,第一个参数设置数组的类型,第二个设置数组的大小。Object array = Array.newInstance(Integer.TYPE,3,3,3);Object array2 = Array.get(array,2);array2 = Array.get(array2,2);Array.setInt(array2,2,10);int[][][] a = (int[][][])array;//打印System.out.println(a[2][2][2]);}
}
打印: 10
使用反射调用类中的私有方法:
例子:
public class PrivateTest {public static void main(String[] args) throws Exception{A a = new A();Class<?> classType = a.getClass();Method method = classType.getDeclaredMethod("getHello",String.class);method.setAccessible(true);//压制Java的访问权限String str = (String)method.invoke(a,"java");System.out.println(str);}
}
class A{private String getHello(String str){return "你好!"+str;}
}
打印:你好!java
如何访问私有属性:
public class Reflection2 {public static void main(String[] args) throws Exception{Private2 p = new Private2();Class<?> cs = p.getClass();Field f = cs.getDeclaredField("name");f.setAccessible(true);//压制Java对方问修饰符的检查f.set(p,"lisi");System.out.println(p.getName());}
}
class Private2 {private String name ;public String getName(){return name;}
}
打印:lisi
通过子类获得父类的Class对象:
public class Test {public static void main(String[] args) {Class<?> classType = Child.class;System.out.println(classType);classType = classType.getSuperclass();System.out.println(classType);classType = classType.getSuperclass();System.out.println(classType);}
}class Child extends Parent{}
class Parent{}
打印:
class Reflection1.Child
class Reflection1.Parent
class java.lang.Object
java(19) - 反射机制相关推荐
- Java的反射机制 工厂模式综合讲解【转载自51CTO】
2019独角兽企业重金招聘Python工程师标准>>> Java的反射机制 工厂模式综合讲解 1.什么叫反射 Java.lang.reflect包下 正常情况下我们可以通过类实例化一 ...
- java xml 反射_Java 读取XML文件以及Java 的反射机制实现
Java 读取XML文件以及Java 的反射机制实现 代码部分 import java.io.File; import javax.xml.parsers.DocumentBuilder; impor ...
- Java编程:Java的反射机制中的 getComponentType() 方法
转载自 Java编程:Java的反射机制中的 getComponentType() 方法 Java 中所有的类都继承自 Object,数组本身也是一个 Class,如果我们能够得到数据的 Class ...
- 搞懂Java的反射机制
搞懂Java的反射机制 1.什么是反射? java的反射机制是指可以在运行状态下获取类和对象的所有属性和方法. 2.反射的作用? 1.在运行时获取一个类/对象的成员变量和方法 2.在运行时创建一个类的 ...
- java原理—反射机制
http://www.cnblogs.com/forlina/archive/2011/06/21/2085849.html 一.什么是反射: 反射的概念是由Smith在1982年首次提出的,主要是指 ...
- java反射之获取class对象,Java之反射机制(获取Class对象的三种方式)
Java之反射机制(获取Class对象的三种方式) 开发工具与关键技术:MyEclipse 10,java 作者:刘东标 撰写时间:2019-06-14 如何得到各个字节码对应的实例对象? 每个类被加 ...
- 学习:java原理—反射机制
一.什么是反射: 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.这一概念的提 出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序 ...
- Java —— Reflect反射机制
JAVA反射机制是在运行时,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java的反射机制. ...
- 什么是Java的反射机制
Java反射机制是Java的特点,是框架实现的基础,百度结果: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这 ...
最新文章
- Nginx rewrite正则匹配重写
- 2019年春节记忆之尹山湖边赏梅
- 如何在服务器端写关闭窗口的代码?同时能够更新父窗口?
- ganglia-介绍安装(二)
- DCMTK:测试框架内容Frame Content FG类
- 一个简单的时间片轮转多道程序内核代码分析
- 一阶网络相应特性的研究_36、 用一阶系统描述的传感器,其动态响应特征的优劣也主要取决于时间常数τ,τ越大越好。( )...
- jboss as7 下载_JBoss AS 7:定制登录模块
- 环形队列出队的元素怎么输出出来_队列的知识讲解与基本实现(数据结构)
- sql server 日期类型
- 自底向上——知识图谱构建技术初探
- 大数据学习知识点导图
- 环境科学跨考专计算机,环境 计算机相结合 跨学科
- 德鲁伊 oltp oltp_内存中OLTP –更快变得更简单!
- Windows域控 添加15分钟无操作自动注销域策略【全域策略生效】
- Eureka微服务之服务核心动作
- 香港云服务器安全吗?
- 企业盈利能力五大指标之:总资产收益率
- 微信公众号第三方平台开发概况
- ArcGIS——使用符号级别区分重叠的面图层