javaweb学习总结四(反射技术)

时间:2025-02-17 11:34:08

一:反射的概念

反射就是加载类,然后获取类的属性、方法、构造函数等。

javaweb学习总结四(反射技术)

二:加载类到内存(有硬盘字节码文件到内存)

javaweb学习总结四(反射技术)

三种加载类的方式:

 @Test
// 测试加载类
public void test1() throws Exception {
// 第一种方式
Class clazz1 = Class.forName("com.hlcui.test.Person");
// 第二种方式
Class clazz2 = new Person().getClass();
// 第三种方式
Class clazz3 = Person.class;
}

三:反射类中的组成部分

1:使用getConstructor()、getMethod()、getField(),可以反射public修饰的成员,

如果需要反射private修饰的成员,需要使用下面的getDeclaredXXX()。

javaweb学习总结四(反射技术)

2:反射构造方法

javaweb学习总结四(反射技术)

Person定义的构造方法:

 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(List<String> list) {
System.out.println(list);
}

反射构造方法代码:

 @Test
// 反射无参构造方法
public void test2() throws Exception {
Class clazz1 = Class.forName("com.hlcui.test.Person");
Constructor c = clazz1.getConstructor(null);
Person p = (Person) c.newInstance(null);
System.out.println(p.name);
} @Test
// 反射参数String的构造方法
public void test3() throws Exception {
Class clazz1 = Class.forName("com.hlcui.test.Person");
Constructor c = clazz1.getConstructor(String.class);
Person p = (Person) c.newInstance("Jack");
System.out.println(p.name);
} @Test
// 反射参数为String、int的构造方法
public void test4() throws Exception {
Class clazz1 = Class.forName("com.hlcui.test.Person");
Constructor c = clazz1.getConstructor(String.class, int.class);
Person p = (Person) c.newInstance("Jack", 27);
System.out.println(p.name);
} @Test
// 反射参数为List的构造方法
public void test5() throws Exception {
Class clazz1 = Class.forName("com.hlcui.test.Person");
Constructor c = clazz1.getDeclaredConstructor(List.class);
c.setAccessible(true);
Person p = (Person) c.newInstance(new ArrayList());
System.out.println(p.name);
}

其中反射参数为List的构造方法,因为构造方法时private修饰的,所以必须使用getDeclaredConstructor()获取构造方法,

同时需要设置强制方法setAccessible(true);

也可以直接使用反射类获取对象,代码如下:

 @Test
public void test6() throws Exception {
Class clazz1 = Class.forName("com.hlcui.test.Person");
Person p = (Person) clazz1.newInstance();
System.out.println(p.name);
}

2:反射方法

javaweb学习总结四(反射技术)

反射方法代码如下:

Person类中定义的普通方法:

 public void abc() {
System.out.println("abc...");
} public String abc(String name) {
return name;
} public void abc(String name, int[] i) {
System.out.println(name + ":" + i);
} public Class[] abc(InputStream in) {
return new Class[] { String.class };
} public static void abc(int i) {
System.out.println(i);
}

反射普通方法:

 @Test
// public void abc()
public void test7() throws Exception {
Person p = new Person();
Class clazz1 = Class.forName("com.hlcui.test.Person");
Method m = clazz1.getMethod("abc", null);
m.invoke(p, null);
} @Test
// public String abc(String name)
public void test8() throws Exception {
Person p = new Person();
Class clazz1 = Class.forName("com.hlcui.test.Person");
Method m = clazz1.getMethod("abc", String.class);
System.out.println(m.invoke(p, "Tom"));
} @Test
// public void abc(String name, int[] i)
public void test9() throws Exception {
Person p = new Person();
Class clazz1 = Class.forName("com.hlcui.test.Person");
Method m = clazz1.getMethod("abc", String.class, int[].class);
m.invoke(p, "Jack", new int[] { 1, 2, 3 });
} @Test
// public Class[] abc(InputStream in)
public void test10() throws Exception {
Person p = new Person();
Class clazz1 = Class.forName("com.hlcui.test.Person");
Method m = clazz1.getMethod("abc", InputStream.class);
Class[] cc = (Class[]) m.invoke(p, new FileInputStream("f:/1.txt"));
System.out.println(cc[0]);
} @Test
// public static void abc(int i)
public void test11() throws Exception {
Class clazz1 = Class.forName("com.hlcui.test.Person");
Method m = clazz1.getMethod("abc", int.class);
m.invoke(null, 27);
}

Person定义的main方法:

 public static void main(String[] args) {
System.out.println("调用main...");
}

反射main方法:

 @Test
// public static void main(String[] args)
public void test12() throws Exception {
Person p = new Person();
Class clazz1 = Class.forName("com.hlcui.test.Person");
Method m = clazz1.getMethod("main", String[].class);
// m.invoke(p, (Object)new String[]{"1","2","3"});
m.invoke(p, new Object[] { new String[] { "1", "2", "3" } });
}

这里要注意,由于jdk5兼容了jdk1.4的特性,传入字符串数组时,它会对传入参数进行拆分,

如:new String[]{"1","2","3"}将被拆分成"1"、"2"、"3",所以直接反射会报参数个数异常,

有两种处理方法:

a:在前面加上Object  b:将数组再次放到数组中

3:反射字段

Person类中定义字段:

 public String name = "Tom";
private int age = 27;
private static double salary = 8000.0;

反射字段:

 @Test
// public String name = "Tom";
public void test13() throws Exception {
Person p = new Person();
Class clazz1 = Class.forName("com.hlcui.test.Person");
Field f = clazz1.getField("name");
f.set(p, "Jack");
Object obj = f.get(p);
Class type = f.getType();
if (type.equals(String.class)) {
String value = (String) obj;
System.out.println(value);
}
} @Test
// private int age = 27;
public void test14() throws Exception {
Person p = new Person();
Class clazz1 = Class.forName("com.hlcui.test.Person");
Field f = clazz1.getDeclaredField("age");
f.setAccessible(true);
int i = (Integer) f.get(p);
System.out.println(i);
} @Test
// private static double salary = 8000.0;
public void test15() throws Exception {
Person p = new Person();
Class clazz1 = Class.forName("com.hlcui.test.Person");
Field f = clazz1.getDeclaredField("salary");
f.setAccessible(true);
double d = (Double) f.get(p);
System.out.println(d);
}

反射的知识就总结到这里!