反射
反射乃框架设计之灵魂。
反射就是把java中类的各种成分映射成一个个的java对象。
必须先得到类的字节码对象:Class clazz = Class.forName(类的完整类名);
如何得到类的字节码对象:(法1扩展性强)
法1: Class.forName(类的完整类名); 如: Class clazz = Class.forName("cn.itcast.base.reflect.Person");
法2: 对象引用名称.getClass(); 如: Class clazz = new Person().getClass();
法3: 类名.class 如: Class clazz = Person.class;
法4: 基本类型的包装类.TYPE(了解) 如 : Integer.TYPE
反射:
分为: 私有(暴力访问)、公有、静态
反射类的构造函数
反射类的一般方法
反射类的字段
注意:
在反射方法时,如果方法的参数是一个数组,考虑到向下兼容问题,会按照JDK1.4的语法来对待
(JVM会把传递的数组参数拆开,拆开就代表参数的个数不匹配)
解决办法:防止JVM拆开你的数组
方式一:把数组看做是一个Object对象
方式二:重新构建一个Object数组,那个参数数组作为唯一的元素存在。
**********************************************************************************************************************************
// 要反射的类:
import java.util.Date;
public class Person {
public String name = "传智播客";
private int age = 18;
public static Date time;
public int getAge(){
return age;
}
public Person(){
System.out.println("默认方法执行...");
}
public Person(String name){
System.out.println("姓名:" + name);
}
public Person(String name, int age){
System.out.println(name + "......" + age);
}
private Person(int age){
System.out.println("年龄:" + age);
}
public void m1(){
System.out.println("m1");
}
public void m2(String name){
System.out.println(name);
}
public String m3(String name, int age){
System.out.println(name + "..." + age);
return "itcast";
}
private void m4(Date d){
System.out.println(d);
}
public static void m5(){
System.out.println("m5");
}
private static void m6(String[] strs){
System.out.println(strs.length);
}
public static void main(String[] args){
System.out.println("main");
}
}
**********************************************************************************************************************************
例1: 反射类中的构造方法
public class Demo {
@Test // 反射: public Person()
public void test1() throws Exception{
// 获取Person类在内存中的字节码对象,有如下3种方式:
Class clazz = Class.forName("cn.itcast.base.reflect.Person");
// 得到构造方法,并创建对象
Constructor c = clazz.getConstructor(null);
c.newInstance(null);
}
@Test // 使用newInstance方法调用默认的构造方法
public void test11() throws Exception{
Class clazz = Class.forName("cn.itcast.base.reflect.Person");
Person p = (Person)clazz.newInstance();
System.out.println(p.name);
}
@Test // 反射: public Person(String name)
public void test2() throws Exception{
Class clazz = Class.forName("cn.itcast.base.reflect.Person");
Constructor c = clazz.getConstructor(String.class);
c.newInstance("谢霆锋");
}
@Test // 反射: public Person(String name,int age)
public void test3() throws Exception{
Class clazz = Class.forName("cn.itcast.base.reflect.Person");
Constructor c = clazz.getConstructor(String.class,int.class);
Person p = (Person)c.newInstance("陈冠希",20);
System.out.println(p.name);
}
@Test // 反射: private Person(int age)
public void test4() throws Exception{
Class clazz = Class.forName("cn.itcast.base.reflect.Person");
// 读取私有的构造方法,并暴力反射
Constructor c = clazz.getDeclaredConstructor(int.class);
c.setAccessible(true);
Person p = (Person)c.newInstance(35);
System.out.println(p.name);
}
@Test // 反射类中的所有的构造方法(包含私有的构造方法)
public void test5() throws Exception{
Class clazz = Class.forName("cn.itcast.base.reflect.Person");
Constructor[] cs = clazz.getDeclaredConstructors();
System.out.println(cs.length);
}
}
**********************************************************************************************************************************
例2: 反射类中的方法(包括main方法)
public class Demo2 {
@Test // 反射public void m1()
public void test1() throws Exception{
Class clazz = Person.class;
Person p = (Person) clazz.newInstance();
// 获取方法: 第一个参数为 方法名称; 第二个参数为: 参数类型
Method m = clazz.getMethod("m1", null);
// 调用方法: 第一个参数为对象名称, 第二个参数为 实际参数
m.invoke(p, null);
}
@Test // 反射public void m2(String name)
public void test2() throws Exception{
Class clazz = Person.class;
Person p = (Person) clazz.newInstance();
Method m = clazz.getMethod("m2", String.class);
m.invoke(p, "谢霆锋");
}
@Test // 反射public String m3(String name, int age)
public void test3() throws Exception{
Class clazz = Person.class;
Person p = (Person) clazz.newInstance();
Method m = clazz.getMethod("m3", String.class,int.class);
String returnValue = (String) m.invoke(p, "谢霆锋",20);
System.out.println(returnValue);
}
@Test // 反射private void m4(Date d)
public void test4() throws Exception{
Class clazz = Person.class;
Person p = (Person) clazz.newInstance();
Method m = clazz.getDeclaredMethod("m4", Date.class);
m.setAccessible(true);
m.invoke(p, new Date());
}
@Test // 反射public static void m5()
public void test5() throws Exception{
Class clazz = Person.class;
Person p = (Person) clazz.newInstance();
Method m = clazz.getMethod("m5", null);
m.invoke(p, null);
}
@Test // 反射public static void m5() 注: 静态的,所以不需要对象,可以省略
public void test51() throws Exception{
Class clazz = Person.class;
Method m = clazz.getMethod("m5", null);
m.invoke(null, null);
}
@Test // 反射private static void m6(String[] strs)
public void test6() throws Exception{
Class clazz = Person.class;
Method m = clazz.getDeclaredMethod("m6", String[].class);
m.setAccessible(true);
// 注: 此处要将数组重新合并为一个数组或对象再传入
// m.invoke(null, new Object[]{new String[]{"a","b"}});
m.invoke(null, (Object)new String[]{"a","b"});
}
@Test // 反射public void main(String[] args)
public void test7() throws Exception{
Class clazz = Person.class;
Method m = clazz.getMethod("main", String[].class);
// 注意:可变数组参数 参数个数的问题 1.4与5.0之间版本的兼容问题
// 1.5中整个数组是一个参数,1.4中数组的每一个元素对应一个参数
m.invoke(null, new Object[]{new String[]{"a","b"}});
}
}
**********************************************************************************************************************************
例3: 反射类中的字段
public class Demo3 {
@Test // 反射: public String name = "传智播客";
public void test1() throws Exception{
// 创建并获取字节码对象
Class clazz = Person.class;
Person p = (Person)clazz.newInstance();
// 获得name字段 : 字节码文件.getField(字段名称);
Field nameF = clazz.getField("name");
// 获得name字段的值 : 字段.get(对象);一般须转换
String s = (String) nameF.get(p);
System.out.println(s);
// 更改name字段的值 如:字段.set(对象,值)
nameF.set(p,"上海传智");
System.out.println(p.name);
}
@Test // 反射:private int age = 18;
public void test2() throws Exception{
Class clazz = Person.class;
Person p = (Person)clazz.newInstance();
Field ageF = clazz.getDeclaredField("age");
ageF.setAccessible(true);
int age = (Integer) ageF.get(p);
System.out.println(age);
ageF.set(p, 28);
// System.out.println(p.getAge());
age = (Integer) ageF.get(p);
System.out.println(age);
}
@Test // 反射: public static Date time
public void test3() throws Exception{
Class clazz = Person.class;
Field timeF = clazz.getField("time");
timeF.set(null, new Date());
System.out.println(Person.time);
}
}
反射乃框架设计之灵魂。
反射就是把java中类的各种成分映射成一个个的java对象。
必须先得到类的字节码对象:Class clazz = Class.forName(类的完整类名);
如何得到类的字节码对象:(法1扩展性强)
法1: Class.forName(类的完整类名); 如: Class clazz = Class.forName("cn.itcast.base.reflect.Person");
法2: 对象引用名称.getClass(); 如: Class clazz = new Person().getClass();
法3: 类名.class 如: Class clazz = Person.class;
法4: 基本类型的包装类.TYPE(了解) 如 : Integer.TYPE
反射:
分为: 私有(暴力访问)、公有、静态
反射类的构造函数
反射类的一般方法
反射类的字段
注意:
在反射方法时,如果方法的参数是一个数组,考虑到向下兼容问题,会按照JDK1.4的语法来对待
(JVM会把传递的数组参数拆开,拆开就代表参数的个数不匹配)
解决办法:防止JVM拆开你的数组
方式一:把数组看做是一个Object对象
方式二:重新构建一个Object数组,那个参数数组作为唯一的元素存在。
**********************************************************************************************************************************
// 要反射的类:
import java.util.Date;
public class Person {
public String name = "传智播客";
private int age = 18;
public static Date time;
public int getAge(){
return age;
}
public Person(){
System.out.println("默认方法执行...");
}
public Person(String name){
System.out.println("姓名:" + name);
}
public Person(String name, int age){
System.out.println(name + "......" + age);
}
private Person(int age){
System.out.println("年龄:" + age);
}
public void m1(){
System.out.println("m1");
}
public void m2(String name){
System.out.println(name);
}
public String m3(String name, int age){
System.out.println(name + "..." + age);
return "itcast";
}
private void m4(Date d){
System.out.println(d);
}
public static void m5(){
System.out.println("m5");
}
private static void m6(String[] strs){
System.out.println(strs.length);
}
public static void main(String[] args){
System.out.println("main");
}
}
**********************************************************************************************************************************
例1: 反射类中的构造方法
public class Demo {
@Test // 反射: public Person()
public void test1() throws Exception{
// 获取Person类在内存中的字节码对象,有如下3种方式:
Class clazz = Class.forName("cn.itcast.base.reflect.Person");
// 得到构造方法,并创建对象
Constructor c = clazz.getConstructor(null);
c.newInstance(null);
}
@Test // 使用newInstance方法调用默认的构造方法
public void test11() throws Exception{
Class clazz = Class.forName("cn.itcast.base.reflect.Person");
Person p = (Person)clazz.newInstance();
System.out.println(p.name);
}
@Test // 反射: public Person(String name)
public void test2() throws Exception{
Class clazz = Class.forName("cn.itcast.base.reflect.Person");
Constructor c = clazz.getConstructor(String.class);
c.newInstance("谢霆锋");
}
@Test // 反射: public Person(String name,int age)
public void test3() throws Exception{
Class clazz = Class.forName("cn.itcast.base.reflect.Person");
Constructor c = clazz.getConstructor(String.class,int.class);
Person p = (Person)c.newInstance("陈冠希",20);
System.out.println(p.name);
}
@Test // 反射: private Person(int age)
public void test4() throws Exception{
Class clazz = Class.forName("cn.itcast.base.reflect.Person");
// 读取私有的构造方法,并暴力反射
Constructor c = clazz.getDeclaredConstructor(int.class);
c.setAccessible(true);
Person p = (Person)c.newInstance(35);
System.out.println(p.name);
}
@Test // 反射类中的所有的构造方法(包含私有的构造方法)
public void test5() throws Exception{
Class clazz = Class.forName("cn.itcast.base.reflect.Person");
Constructor[] cs = clazz.getDeclaredConstructors();
System.out.println(cs.length);
}
}
**********************************************************************************************************************************
例2: 反射类中的方法(包括main方法)
public class Demo2 {
@Test // 反射public void m1()
public void test1() throws Exception{
Class clazz = Person.class;
Person p = (Person) clazz.newInstance();
// 获取方法: 第一个参数为 方法名称; 第二个参数为: 参数类型
Method m = clazz.getMethod("m1", null);
// 调用方法: 第一个参数为对象名称, 第二个参数为 实际参数
m.invoke(p, null);
}
@Test // 反射public void m2(String name)
public void test2() throws Exception{
Class clazz = Person.class;
Person p = (Person) clazz.newInstance();
Method m = clazz.getMethod("m2", String.class);
m.invoke(p, "谢霆锋");
}
@Test // 反射public String m3(String name, int age)
public void test3() throws Exception{
Class clazz = Person.class;
Person p = (Person) clazz.newInstance();
Method m = clazz.getMethod("m3", String.class,int.class);
String returnValue = (String) m.invoke(p, "谢霆锋",20);
System.out.println(returnValue);
}
@Test // 反射private void m4(Date d)
public void test4() throws Exception{
Class clazz = Person.class;
Person p = (Person) clazz.newInstance();
Method m = clazz.getDeclaredMethod("m4", Date.class);
m.setAccessible(true);
m.invoke(p, new Date());
}
@Test // 反射public static void m5()
public void test5() throws Exception{
Class clazz = Person.class;
Person p = (Person) clazz.newInstance();
Method m = clazz.getMethod("m5", null);
m.invoke(p, null);
}
@Test // 反射public static void m5() 注: 静态的,所以不需要对象,可以省略
public void test51() throws Exception{
Class clazz = Person.class;
Method m = clazz.getMethod("m5", null);
m.invoke(null, null);
}
@Test // 反射private static void m6(String[] strs)
public void test6() throws Exception{
Class clazz = Person.class;
Method m = clazz.getDeclaredMethod("m6", String[].class);
m.setAccessible(true);
// 注: 此处要将数组重新合并为一个数组或对象再传入
// m.invoke(null, new Object[]{new String[]{"a","b"}});
m.invoke(null, (Object)new String[]{"a","b"});
}
@Test // 反射public void main(String[] args)
public void test7() throws Exception{
Class clazz = Person.class;
Method m = clazz.getMethod("main", String[].class);
// 注意:可变数组参数 参数个数的问题 1.4与5.0之间版本的兼容问题
// 1.5中整个数组是一个参数,1.4中数组的每一个元素对应一个参数
m.invoke(null, new Object[]{new String[]{"a","b"}});
}
}
**********************************************************************************************************************************
例3: 反射类中的字段
public class Demo3 {
@Test // 反射: public String name = "传智播客";
public void test1() throws Exception{
// 创建并获取字节码对象
Class clazz = Person.class;
Person p = (Person)clazz.newInstance();
// 获得name字段 : 字节码文件.getField(字段名称);
Field nameF = clazz.getField("name");
// 获得name字段的值 : 字段.get(对象);一般须转换
String s = (String) nameF.get(p);
System.out.println(s);
// 更改name字段的值 如:字段.set(对象,值)
nameF.set(p,"上海传智");
System.out.println(p.name);
}
@Test // 反射:private int age = 18;
public void test2() throws Exception{
Class clazz = Person.class;
Person p = (Person)clazz.newInstance();
Field ageF = clazz.getDeclaredField("age");
ageF.setAccessible(true);
int age = (Integer) ageF.get(p);
System.out.println(age);
ageF.set(p, 28);
// System.out.println(p.getAge());
age = (Integer) ageF.get(p);
System.out.println(age);
}
@Test // 反射: public static Date time
public void test3() throws Exception{
Class clazz = Person.class;
Field timeF = clazz.getField("time");
timeF.set(null, new Date());
System.out.println(Person.time);
}
}