一个类有多个组成部分,例如:成员变量,方法,构造方法等。反射就是加载类,并解剖出类的各个组成部分。

编程时什么情况下才需要加载类,并解剖出累的各个组成部分呢?

反射是用来做框架的。

从配置文件中解读类的方法等。

Java中有一个Class类用于代表某一个类的字节码。

Class类既然代表某个类的字节码,它当然就要提供加载某个类自己吗的方法:forName(). forName方法用于加载某个类的字节码到内存中,并使用class对象进行封装。

另外两种得到class对象的方式

类名.class

对象.getClass()

下面看三种类的加载方法

 package cn.itcast.reflect;

 public class Demo1 {

     public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
//加载类的字节码1,常用
Class clazz1 = Class.forName("cn.itcast.reflect.Person"); //加载类的字节码2
Class clazz2 = Person.class; //加载类的字节码3
Class clazz3 = new Person().getClass(); } }

Class对象提供了如下常用方法:

 public Constructor getConstructor(Class<?>... parameterTypes)
public Method getMethod(String name,Class<?>... parameterTypes)
public Field getField(String name) public Constructor getDeclaredConstructor(Class<?>... parameterTypes)
public Method getDeclaredMethod(String name,Class<?>... parameterTypes)
public Field getDeclaredField(String name)

这些方法分别用于从类中解剖出构造函数、方法和成员变量(属性)。解剖出的成员分别使用Constructor,Method,Field对象表示。

思考:假设你是一个框架的设计者,出这些成员后你会干什么?

先看反射类的构造方法。

 //Demo1.java
package cn.itcast.reflect;
import java.lang.reflect.Constructor;
import org.junit.Test;
public class Demo1 { public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
//加载类的字节码1,常用
Class clazz = Class.forName("cn.itcast.reflect.Person");
Constructor c = clazz.getConstructor(null); Object obj = c.newInstance(null); System.out.println(obj); } //反射无参的构造函数
@Test
public void test1() throws Exception{
Class clazz = Class.forName("cn.itcast.reflect.Person");
Constructor c = clazz.getConstructor(null); Object obj = c.newInstance(null); System.out.println(obj);
} //反射有参的构造函数
@Test
public void test2() throws Exception{
Class clazz = Class.forName("cn.itcast.reflect.Person");
Constructor c = clazz.getConstructor(String.class); Person p = (Person) c.newInstance("fix");
System.out.println(p);
} //反射私有的,有参的构造函数
@Test
public void test3() throws Exception{
Class clazz = Class.forName("cn.itcast.reflect.Person");
Constructor c = clazz.getDeclaredConstructor(int.class);
c.setAccessible(true);//暴力反射
Person p = (Person) c.newInstance(1);
System.out.println(p);
}
}

下面看反射类的方法

 package cn.itcast.reflect;

 import java.lang.reflect.Method;

 import org.junit.Test;

 public class Demo2 {
//反射方法 //反射不带参数的方法
@Test
public void test1() throws Exception{
Class clazz = Class.forName("cn.itcast.reflect.Person"); Method method = clazz.getMethod("eat", null); method.invoke(clazz.newInstance(), null);
} //反射带参数的方法
@Test
public void test2() throws Exception{
Class clazz = Class.forName("cn.itcast.reflect.Person"); Method method = clazz.getMethod("run", String.class); method.invoke(clazz.newInstance(), "上海");
} //反射带多个参数的方法
@Test
public void test3() throws Exception{
Class clazz = Class.forName("cn.itcast.reflect.Person"); Method method = clazz.getMethod("run", String.class,int[].class,String[].class); method.invoke(clazz.newInstance(), "上海",new int[]{1,2,3},new String[]{"a","b","c"});
} //反射带返回值的方法
@Test
public void test4() throws Exception{
Class clazz = Class.forName("cn.itcast.reflect.Person"); Method method = clazz.getMethod("test", String.class); String result = (String) method.invoke(clazz.newInstance(), "上海");
System.out.println(result);
} //反射私有方法
@Test
public void test5() throws Exception{
Class clazz = Class.forName("cn.itcast.reflect.Person"); Method method = clazz.getDeclaredMethod("test2", String.class);
method.setAccessible(true);//暴力反射
String result = (String) method.invoke(clazz.newInstance(), "上海");
System.out.println(result);
} //反射静态方法
@Test
public void test6() throws Exception{
Class clazz = Class.forName("cn.itcast.reflect.Person"); Method method = clazz.getMethod("test3", String.class);
String result = (String) method.invoke(null, "上海");
System.out.println(result);
} //反射main方法
//通过反射调用带数组的方法,要注意处理
@Test
public void test7() throws Exception{
Class clazz = Class.forName("cn.itcast.reflect.Person"); Method method = clazz.getMethod("main", String[].class);
//method.invoke(null, (Object)new String[]{"1","2"});
method.invoke(null, new Object[]{new String[]{"1","2"}});
}
}

利用Field访问属性

Field对象提供了如下方法,用于设置、获取对象属性的值:

public void set(Object obj,Object value)

public Object get(Object obj)

 package cn.itcast.reflect;

 import java.lang.reflect.Field;

 import org.junit.Test;

 public class Demo3 {

     /**
* 反射类的字段
* @throws Exception
*/
//反射公有成员变量
@Test
public void test1() throws Exception{ Person p = new Person();
Class clazz = Class.forName("cn.itcast.reflect.Person"); Field f = clazz.getField("name"); f.set(p, "flx");
System.out.println(p.getName()); } //反射公有成员变量
@Test
public void test2() throws Exception{ Person p = new Person();
p.setName("xxx");
Class clazz = Class.forName("cn.itcast.reflect.Person");
Field f = clazz.getField("name");
String result = (String)f.get(p);
System.out.println(result); } //反射final成员变量
@Test
public void test3() throws Exception{ Person p = new Person();
Class clazz = Class.forName("cn.itcast.reflect.Person");
Field f = clazz.getField("password");
String result = (String)f.get(p);
System.out.println(result); } //反射私有成员变量
@Test
public void test4() throws Exception{
Person p = new Person();
Class clazz = Class.forName("cn.itcast.reflect.Person");
Field f = clazz.getDeclaredField("age");
f.setAccessible(true);
f.set(p, 123);
int result = (Integer)f.getInt(p);
System.out.println(result);
}
}

Person类如下:

 package cn.itcast.reflect;

 public class Person {

     public String name;//字段或成员变量
private int age; public final String password="123"; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public Person(){
System.out.println("person");
} public Person(String name){
System.out.println(name);
} private Person(int name){
System.out.println(name);
} public void eat(){
System.out.println("eat!!!");
} public void run(String address){
System.out.println("跑到"+address);
} public void run(String address,int num[],String ss[]){
System.out.println("跑到"+address+"," +num);
} public String test(String str){
return str+"aaaaaa";
} private String test2(String str){
return str+"aaaaaa";
} public static String test3(String str){
return str+"aaaa";
} public static void main(String[] args) {
System.out.println(args[0]);
} }

如上就是反射所有常用的一些方法。

最新文章

  1. date 显示或设置系统时间和日期
  2. 经典收藏 50个jQuery Mobile开发技巧集萃
  3. BLE蓝牙通信指令交互过程配对与绑定
  4. C#虚方法认识
  5. cmd命令。
  6. boost.asio源码剖析
  7. python 基础——实现一个带缓存功能的函数
  8. SQL Server DBA工作内容详解
  9. 开源免费跨平台opengl opencv webgl gtk blender, opengl贴图程序
  10. iOS 打包上传AppStore相关(3)-iTunes相应配置以及使用蒲公英网站进行应用托管分发(链接/二维码)
  11. Selenium IDE安装
  12. 【liferay】1、使用alloy-UI发送ajax请求
  13. webpack3配置字体图标和打包相关问题
  14. Mego开发文档 - 数据注释建模
  15. Java开源生鲜电商平台-系统架构与技术选型(源码可下载)
  16. 【POJ 3159】Candies&amp;&amp;洛谷P3275 [SCOI2011]糖果
  17. jmeter 使用问题
  18. lamp虚拟主机的常用配制选项
  19. TP5:使用了INPUT函数来接收参数了,还需再过滤SQL注入吗
  20. localstrage、cookie、session等跨域和跨页面监听更新问题

热门文章

  1. ugui Event.current.mousePosition获取的坐标原点在左上角
  2. poj1778
  3. HDU - 5412 CRB and Queries (整体二分)
  4. Java模版引擎:jsp、freemarker、velocity区别
  5. 六、python沉淀之路--int str list tuple dict 重点总结
  6. jsp中引入JavaScript的方法
  7. Linux下markdown编辑软件 — retext 支持实时预览,存为pdf、html、ODT等
  8. BZOJ1047:[HAOI2007]理想的正方形
  9. MSSQL Join的使用
  10. Hybrid APP混合开发