1.反射:一个类有多个组成部分,比如成员方法,成员变量,构造函数。反射就是加载类,并且去解剖出类的各个组成部分。
2.加载类:java中有一个Class类用于代表某一个类的代码。
3.Class类既然代表某个类的字节码,那么必然提供了加载某个字节码的方法,例如:
forName(),forName()用于加载某个类的字节码到内存中,并且使用Class对象进行封装。
另外二种得到Class对象方式:
1.类名.class:Person.class
2.对象.getClass().:new Person().getClass()
4.内省(Introspector)
主要用于操作javabean的属性
内省访问javabean属性的二种方式。
1.通过PropertyDescriptor类操作javabean的属性。
2.通过Introspector类获得bean对象的beaninfo,然后通过BeanInfo来获取属性的描述器
(PropertyDescriptor),通过属性描述器就就可以获取属性的getter和setter方法,最后通过反射调用这些方法.
5..反射案例
1.创建一个Person类.
package com.cn.fanshe;
import java.awt.List;
import java.io.InputStream;
public class Person {
public String name="aaa";
private String passwd;
private static int num;
public Person(){
System.out.println("person");
}
public Person(String name){
System.out.println(name);
}
public Person(String name,String passwd){
System.out.println(name +"and"+ passwd);
}
private Person(List list){
System.out.println("list");
}
public void add(){
System.out.println("add");
}
public void add(String name){
System.out.println(name);
}
public Class[] add(String name,int[] i){
return new Class[]{};
}
private void add(InputStream in){
System.out.println(in);
}
public static void add(int passwd){
System.out.println(passwd);
}
public static void main(String[] args) {
System.out.println("main");
}
}
2.获取类的字节码的三种方式
package com.cn.fanshe;
public class Demo {
public static void main(String[] args) throws ClassNotFoundException {
//第一种方式:反射,加载类,参数是类的完整类名
Class cl=Class.forName("com/cn/fanshe/Person.java");
//第二种方式:对象.getClass().
Class clazz=new Person().getClass();
//第三种方式:类名.class
Class cla=Person.class;
}
}
3.反射类的构造函数
package com.cn.fanshe;
import java.awt.List;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
/*
* 反射类的构造函数
*/
public class Demo2 {
//public Person:反射构造函数,创建类的对象
public void test1() throws Exception{
//加载类,将类的字节码加载到内存中
Class clazz=Class.forName("com/cn/fanshe/Person.java");
Constructor c=clazz.getConstructor(null);
Person p=(Person)c.newInstance(null);
System.out.println(p.name);
}
//public Person(String name):
public void test2() throws Exception{
Class clazz=Class.forName("com/cn/fanshe/Person.java");
Constructor c=clazz.getConstructor(String.class);
Person p=(Person)c.newInstance("hello");
System.out.println(p.name);
}
//public Person(String name,String passwd)
public void test3() throws Exception{
Class clazz=Class.forName("com/cn/fanshe/Person.java");
Constructor c=clazz.getConstructor(String.class,String.class);
Person p=(Person)c.newInstance("hello","1232");
System.out.println(p.name);
}
//private Person(List list);
public void test4() throws Exception{
Class clazz=Class.forName("com/cn/fanshe/Person.java");
Constructor c=clazz.getDeclaredConstructor(List.class);//当构造函数设置为private,反射时必须使用getDeclaredConstructor();
c.setAccessible(true);//当构造函数设置为private时,设置可以强制反射
Person p=(Person)c.newInstance(new ArrayList());
System.out.println(p.name);
}
//创建对象的另一种途径,等效于test1()。当构造函数无参数时使用.
public void test5() throws Exception{
Class clazz=Class.forName("com/cn/fanshe/Person.java");
Person p=(Person)clazz.newInstance();
System.out.println(p.name);
}
}
3.反射类的方法
package com.cn.fanshe;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
/*
* 反射类的成员方法
*/
public class Demo3 {
//反射类的成员方法:public void add();
public void test1() throws Exception{
Person p=new Person();
Class clazz=Class.forName("com/cn/fanshe/Person.java");
Method method=clazz.getMethod("add",null);
method.invoke(p, null);
}
//public void add(String name);
public void test2() throws Exception{
Person p=new Person();
Class clazz=Class.forName("com/cn/fanshe/Person.java");
Method method=clazz.getMethod("add",String.class);
method.invoke(p, "hello");
}
//public void add(String name,int[] i);
public void test3() throws Exception{
Person p=new Person();
Class clazz=Class.forName("com/cn/fanshe/Person.java");
Method method=clazz.getMethod("add",String.class,int[].class);
Class[] ca=(Class[])method.invoke(p, "qwer",new int[]{1,23});
}
//private void add(InputStrream in);
public void test4() throws Exception{
Person p=new Person();
Class clazz=Class.forName("com/cn/fanshe/Person.java");
Method method=clazz.getDeclaredMethod("add",InputStream.class);
method.setAccessible(true);
method.invoke(p, new FileInputStream("c://1.txt"));
}
//public static void add();
public void test5() throws Exception{
//因为反射静态方法,所以对象为null;
Class clazz=Class.forName("com/cn/fanshe/Perosn.java");
Method method=clazz.getMethod("addd",int.class);
method.invoke(null,334);
}
}
4.反射类的字段
package com.cn.fanshe;
import java.lang.reflect.Field;
/*
* 反射类的字段或者说是属性
*/
public class Demo5 {
//反射字段:public String name="aaaa";
public void test1() throws Exception{
Person p=new Person();
Class clazz=Class.forName("com/cn/fanshe/Person.java");
Field f=clazz.getField("name");
//f.get(p):获取字段的值
String s=(String)f.get(p);
System.out.println(s);
//获取字段的类型
Class cl=f.getType();
System.out.println(cl);
//设置字段的值
f.set(p, "ghj");
System.out.println(p.name);
}
//反射字段:private String passwd;
public void test2() throws Exception{
Person p=new Person();
Class clazz=Class.forName("com/cn/fanshe/Person.java");
Field f=clazz.getDeclaredField("passwd");
f.setAccessible(true);
System.out.println(f.get(p));
}
//反射字段:private static int num;
public void test3() throws Exception{
Person p=new Person();
Class clazz=Class.forName("com/cn/fanshe/Person.java");
Field f=clazz.getDeclaredField("num");
f.setAccessible(true);
String s=(String)f.get(p);
System.out.println(s);
}
}
1.创建一个Perosnd类
package com.cn.introspector;
public class Person {
private String name;
private int passwd;
private static int num;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPasswd() {
return passwd;
}
public void setPasswd(int passwd) {
this.passwd = passwd;
}
public static int getNum() {
return num;
}
public static void setNum(int num) {
Person.num = num;
}
}
2.获取属性和属性的数据类型
package com.cn.introspector;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
public class Demo {
//遍历类的属性
public void test1() throws Exception{
BeanInfo info=Introspector.getBeanInfo(Person.class,Object.class);//得到自己的属性,除去了Object的属性了
PropertyDescriptor[] pd=info.getPropertyDescriptors();//获取属性描述器
for (PropertyDescriptor pr : pd) {
System.out.println(pr.getName());//获取bean里面的属性名
}
}
//操作bean的指定属性;name
public void test2() throws Exception{
Person p=new Person();
PropertyDescriptor pd=new PropertyDescriptor("name",Person.class);
//操作属性的值,给属性赋值.
Method method=pd.getWriteMethod();//相当于public void setName();
method.invoke(p, "heool");
//操作属性的值,读取属性的值
Method md=pd.getReadMethod();
System.out.println(md.invoke(p, "name"));
}
//获取属性的数据类型
public void test3() throws Exception{
Person p=new Person();
PropertyDescriptor pd=new PropertyDescriptor("name", Person.class);
System.out.println(pd.getPropertyType());
}
public static void main(String[] args) throws Exception {
new Demo().test3();
}
}
7.反射和内省的区别
内省,是对javabean对象的操作,反射就是把一个普通类中的每个组成部分都可以单独取出来,对每一个成员的调用或者修改不必依赖于new对象。