------- android培训、java培训、期待与您交流!----------
当我们写好一个程序时,Java 语言把每个单独的类 Class 和接口 Implements 编译成单独的一个 . class 文件,这些文件对于 Java 运行环境来说就是一个个可以动态加载的单元。此外这些class文件就是这些类或接口的字节码文件,为了操作这些字节码文件,java把这些字节码文件归为Class类。
那么怎样来理解Class类呢?
类就是一些具有相同特性的对象的抽象形式,比如Person类,就把人的姓名,年龄,身高等共有的数据给抽象出来。
而Class类就是所有类字节码文件对象的抽象形式,所有的类都是具有字段,构造方法,成员方法这些相同的元素,
Class类就把这些类共有的特性分为了Field,Constructor,Method类。
而反射就是建立在Class类的基础上来动态的获取类中的信息,调用这些类的方法和属性,要想操作这些类必须先获得这些类的字节码文件对象。比如Person类就具有自己特有的字节码文件,他的对象P1和P2所对应的类的字节码文件都是一样的。
下面通过一个例子就把关于反射的大部分操作方法给展现出来。
//定义一个Person类,分别有公有和私有的构造方法、字段和方法,然后用反射来操作这个类
public class Person {
private String namePrivate;
public static int ageStatic;
public String namePublic;
public int agePublic;
Person() {
}
public Person(String namePublic,int agePublic)
{
this.namePublic = namePublic;
this.agePublic = agePublic;
System.out.println("我是公有构造方法"+"公有字段"+namePublic+agePublic);
}
public Person(int agePublic)
{
this.agePublic = agePublic;
}
private Person(String namePrivate)
{
this.namePrivate = namePrivate;
System.out.println("我是私有有构造方法"+"私有字段"+namePrivate);
}
public Person getPersonPublic(String namePublic ,int agePublic )
{
this.agePublic = agePublic;
this.namePublic = namePublic;
Person p = new Person();
return p;
}
public int getAgePublic()//空参数的构造方法
{
return agePublic;
}
private String getNamePrivate(String name)
{
return namePrivate;
}
public static int getAgeStatic(int age)
{
Person.ageStatic = age;
return ageStatic;
}
}
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import javax.activation.FileDataSource;
import cn.cn.cn.Student;
public class ClassDemo {
public static void main(String[] args) throws Exception
{
new Student();
/*
* 有三种方式可以得到Person类的Class
* 方式一:知道Person的一个对象p
* Class c1 = p.getClass();
* 方式二:知道有个类叫Person
* Class c2 = Person.class;
* 方式三:知道有个类叫Person 此种方式的字符串参数要包括包名,一般是通过配置文件获得的
* Class c3 = Class.forName("Person");
*/
//方式一:必须要先有个对象
Person p = new Person();
Class c1 = p.getClass();
//方式二
Class c2 = Person.class;
// 方式三
Class c3 = Class.forName("Person");//Person保存在默认包中
//如果我们定义一个Student类他的包名为 cn.cn.cn,用之前先导入包,最上面:import cn.cn.cn.Student;
Class c4 = Class.forName("cn.cn.cn.Student");
System.out.println(c4);
/*
1 * 构造方法的获得方式
*
* 1.获得公有的构造方法
* 1.1获得所有的公有方法
* 1.2获得指定的公有方法
* 2.获得所有的构造方法
* 2.1获得所有的方法
* 2.2获得指定的私有方法
*/
//1.1获得所有公有的构造方法,调用Class对象的getConstructors方法,他会返回返回一个包含某些 Constructor 对象的数组
Constructor[] cons = c1.getConstructors();
for(Constructor s : cons)
{
System.out.println(s); //打印结果public Person(int) public Person(java.lang.String,int)
}
// 1.2 获得指定的公有方法,调用Class方法的getConstructor方法,返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
//指定的方法就是将构造方法的参数值传入
Constructor con = c1.getConstructor(String.class,int.class);
System.out.println(con); // public Person(java.lang.String,int)
// 2.获得所有的私有方法以及指定的私有方法,与上面的方法类似,就多了个Declared关键字
Constructor[] conprs = c1.getDeclaredConstructors();
Constructor conpr = c1.getDeclaredConstructor(String.class);
/***************************************************************************************/
/*
2 * 获得字段的方法
2.1获得所有的公有字段
2.2获得所有的字段
2.3获得指定的私有字段
*/
//获得所有的公有字段
Field[] filed = c1.getFields();
//获得所有的 私有有字段
Field[] fieldpr = c1.getDeclaredFields();
//获得指定的私有字段namePrivate
Field f = c1.getDeclaredField("namePrivate");
System.out.println(f);
/***************************************************************************************/
/*
3 * 获得字段的方法
3.1获得所有的公有方法
3.2获得所有的方法
3.3获得指定的公有方法
3.4获得静态方法
*/
//3.1获得所有的公有方法
Method [] ms = c1.getMethods();
//3.1获得所有的方法
Method [] mps = c1.getDeclaredMethods();
//3.3获得指定的公有方法,调用getDeclaredMethod(String name ,Class<?>... parameterTypes)
// 他又两个参数,name 参数是一个 String,它指定所需方法的简称,parameterTypes 参数是 Class 对象的一个数组,
//它按声明顺序标识该方法的形参类型。
Method m = c1.getDeclaredMethod("getNamePrivate", String.class);
//如果想获取空参数的构造方法,将参数表写为null就行了
Method mnull = c1.getMethod("getAgePublic", null);
//3.4获得静态方法,和普通的获得方法没什么不同
Method mm = c1.getMethod("getAgeStatic", int.class);
/***************************************************************************************/
/*
4 如何利用反射实例化一个对象,并使用它的方法
4.1利用方式实例化一个对象
4.1.1利用默认的无参构造函数实例化一个对象
4.1.2利用指定的公共的构造函数实例化一个对象
4.1.3利用指定的私有的构造函数实例化一个对象
4.2利用反射使用方法
4.2.1使用公共的方法
4.2.2使用私有的方法
4.2.3使用静态方法
* */
// 4.1.1利用默认的无参构造函数实例化一个对象
Person p1 = (Person)c1.newInstance();
// 4.1.2利用指定的公共的构造函数实例化一个对象
Constructor con1 = c1.getConstructor(String.class,int.class);
Person p2 = (Person)con1.newInstance("liming",20);
System.out.println(p2.agePublic+p2.namePublic);
//利用指定的私有的构造函数实例化一个对象
Constructor con3 = c1.getDeclaredConstructor(String.class);
//私有的必需要设置访问权限,否则不能访问,对于字段和方法也是一样的
con3.setAccessible(true);
con3.newInstance("wang");
// 4.2.1使用公共的方法
Method m1 = c1.getMethod("getAgePublic", null);
Object obj = c1.newInstance();
int age = (Integer) m1.invoke(obj, null);
//4.2.2使用私有的方法,与上面类似,只要设置权限就可以了
//4.2.3使用静态方法。和上面类似,只要invoke的第一个参数设为null
Method m2 = c1.getMethod("getAgeStatic", int.class);
int age1 = (Integer) m2.invoke(null, 24);
System.out.println(age1);
}
}