Class<T>类(在java.lang包中,Instances of the class Classrepresent classes and interfaces in a running Javaapplication):在Java中,每个class都有一个相应的Class对象。也就是说,当我们编写一个类,编译完成后,在生成的.class文件中,就会产生一个Class对象,用于表示这个类的类型信息。
T - 由此 Class 对象建模的类的类型。例如,String.class 的类型是Class<String>。如果将被建模的类未知,则使用 Class<?>。
User类
package com.test.reflect;
/**
* @author cxl
* 2013-10-26
*/
public class User {
private String name;
private int age;
public User() {
}
public User(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
System.out.println("getter name is " + this.name);
return name;
}
public void setName(String name) {
this.name = name;
System.out.println("setter name is " + name);
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User [age=" + age + ", name=" + name + "]";
}
public String getCountryInfo(String country) {
return "I come from " + country;
}
private String sayHello(String name) {
return "hello," + name;
}
}
获取Class类的对象
一、通过getClass()方法获取
利用对象调用getClass()方法获取该对象的Class实例;
二、通过forName()方法获取
使用Class类的静态方法forName(),用类的名字获取一个Class实例
三、通过类.class方式获取
使用类.class方式Class实例,对于基本数据类型的封装类,还可以采用.TYPE来获取相对应的基本数据类型的Class实例
利用对象调用getClass()方法获取该对象的Class实例;
二、通过forName()方法获取
使用Class类的静态方法forName(),用类的名字获取一个Class实例
三、通过类.class方式获取
使用类.class方式Class实例,对于基本数据类型的封装类,还可以采用.TYPE来获取相对应的基本数据类型的Class实例
DemoClass类
import com.test.reflect.User;
public class DemoClass {
public static void main(String[] args) throws Exception {
User u = new User();
// 1.通过getClass()方法获取
Class<?> userClass1 = u.getClass();
System.out.println(userClass1.getName());//com.test.reflect.User
// 2.通过forName()方法获取
Class<?> userClass2 = Class.forName("com.test.reflect.User");
System.out.println(userClass2.getName());//com.test.reflect.User
// 3.通过类.class方式获取
Class<?> userClass3 = User.class;
System.out.println(userClass3.getName());//com.test.reflect.User
// 基础类型.class方式
Class<?> userClass4 = int.class;
System.out.println(userClass4.getName());//int
// 基础类型包装类.TYPE获取
Class<?> userClass5 = Integer.TYPE;
System.out.println(userClass5.getName());//int
// 基础类型包装类.class
Class<?> userClass6 = Integer.class;
System.out.println(userClass6.getName());//java.lang.Integer
}
}
获取相应类的实例化对象
DemoInstance类
import java.lang.reflect.Constructor;
import com.test.reflect.User;
public class DemoInstance {
public static void main(String[] args) throws Exception {
Class<?> userClass = Class.forName("com.test.reflect.User");
//获取所有构造方法
Constructor<?>[] constructors = userClass.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
//public com.test.reflect.User(java.lang.String,int)
//public com.test.reflect.User()
}
//一、根据指定的构造方法实例化对象
//1.通过无参的构造方法实例化对象
User user = (User)userClass.newInstance();
user.setName("hello");//setter name is hello
user.setAge(25);
user.getName();//getter name is hello
System.out.println(user);//User [age=25, name=hello]
//2.通过有参的构造方法实例化对象
Constructor<?> constructor = userClass.getConstructor(String.class,int.class);
//Constructor<?> constructor = userClass.getConstructor(new Class[]{String.class,int.class});
User u = (User)constructor.newInstance("world",27);
//User u = (User)constructor.newInstance(new Object[]{"world",27});
System.out.println(u);//User [age=27, name=world]
//二、根据构造方法的数组实例化对象(注意得到构造方法的顺序)
User u1 = (User)constructors[0].newInstance("cxl",25);
System.out.println(u1);//User [age=25, name=cxl]
User u2 = (User)constructors[1].newInstance();
System.out.println(u2);//User [age=0, name=null]
}
}
获取class对象中的方法
import java.lang.reflect.Method;
public class DemoMethod {
public static void main(String[] args) throws Exception {
Class<?> userClass = Class.forName("com.test.reflect.User");
//1.getMethods()获取类public的方法(包括继承的方法)
Method[] methods1 = userClass.getMethods();
System.out.println("getMethods()获取的方法有:");
for (Method method : methods1) {
System.out.println(method);
}
//2.getDeclaredMethods()获取类的所有方法(但不包含继承的方法)
System.out.println("getDeclaredMethods()获取的方法有:");
Method[] methods2 = userClass.getDeclaredMethods();
for(Method method : methods2){
System.out.println(method);
}
}
}
打印结果:
getMethods()获取的方法有:
public int com.test.reflect.User.getAge()
public void com.test.reflect.User.setAge(int)
public int com.test.reflect.User.add(int,int)
public java.lang.String com.test.reflect.User.toString()
public java.lang.String com.test.reflect.User.getName()
public void com.test.reflect.User.setName(java.lang.String)
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public boolean java.lang.Object.equals(java.lang.Object)
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
getDeclaredMethods()获取的方法有:
public int com.test.reflect.User.getAge()
public void com.test.reflect.User.setAge(int)
public int com.test.reflect.User.add(int,int)
public java.lang.String com.test.reflect.User.toString()
public java.lang.String com.test.reflect.User.getName()
public void com.test.reflect.User.setName(java.lang.String)
获取class对象中的属性
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class DemoField {
public static void main(String[] args) throws Exception {
Class<?> userClass = Class.forName("com.test.reflect.User");
Field[] fields = userClass.getDeclaredFields();
for (Field field : fields) {
//获取属性
System.out.println("属性 :" + field.getName());
int mod = field.getModifiers();
//获取属性修饰符
System.out.println("属性修饰符 :" + Modifier.toString(mod));
//获取属性类型
System.out.println("属性类型:" + field.getType().getName());
System.out.println(Modifier.toString(mod) + " " +
field.getType().getName() + " " + field.getName());
}
}
}
打印结果:
属性 :name
属性修饰符 :private
属性类型:java.lang.String
private java.lang.String name
属性 :age
属性修饰符 :private
属性类型:int
private int age
通过
getFields()方法可以获取父类或者接口的public属性,getDeclaredFields()获得某个类的所有申明的属性,类似的方法有getConstructors()和getDeclaredConstructors(),getMethods()和getDeclaredMethods()。
通过getInterfaces()方法获取实现的接口,通过getSuperclass()方法获取继承类
通过反射调用方法
DemoInvoke类
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import com.test.reflect.User;
/**
* 反射调用方法
*/
public class DemoInvoke {
public static void main(String[] args) throws Exception {
Class<?> userClass = Class.forName("com.test.reflect.User");
User user = (User) userClass.newInstance();
/**
* 通过反射调用User类的普通方法 getMethod(String name, Class<?>... parameterTypes)
* name指调用的方法名 ,parameterTypes是指按声明顺序标识该方法入参类型的 Class对象的一个数组 可以通过
* new Class数组完成,如new Calss[]{String.class}{}中是入参类型的Class对象
*/
Method method = userClass.getMethod("getCountryInfo", String.class);
String countryInfo = (String)method.invoke(user, "China");
System.out.println(countryInfo);//I come from China
/**
* 调用反射User类的setter,getter方法
*/
Field[] fields = userClass.getDeclaredFields();
for (Field field : fields) {
//属性
String fieldName = field.getName();
//setter方法名
String setterName = "set" + fieldName.substring(0, 1).toUpperCase()
+ fieldName.substring(1);
//getter方法名
String getterName = "get" + fieldName.substring(0, 1).toUpperCase()
+ fieldName.substring(1);
//获取setter方法
Method setterMethod = userClass.getMethod(setterName,
new Class[] {field.getType()});
//获取getter方法
Method getterMethod = userClass.getMethod(getterName,
new Class[] {});
System.out.println(field.getType().getSimpleName());//String int
//setter方法
if(field.getType().getName().equals("java.lang.String")) {
setterMethod.invoke(user, "test");//setter name is test
}
if(field.getType().getName().equals("int")) {
setterMethod.invoke(user, 25);
}
Object fieldValue = getterMethod.invoke(user);//getter name is test
System.out.println("field : " + fieldName + " = " + fieldValue);
}
System.out.println(user);//User [age=25, name=test]
DemoInvoke demoInvoke = new DemoInvoke();
user = new User("lucy",18);
User userCopy = (User)demoInvoke.copy(user);
System.out.println(userCopy);//User [age=18, name=lucy]
}
/**
* 实现对User对象的拷贝
* @param obj
* @return
* @throws Exception
*/
public Object copy(Object obj) throws Exception {
//获取obj的Class对象
Class<?> objClass = obj.getClass();
//通过相应的Class对象的newInstance()new一个要返回的对象
Object objCopy = objClass.newInstance();
/*等价于Object objCopy = objClass.getConstructor(new Class[] {})
.newInstance(new Object[] {});*/
Field[] fields = objClass.getDeclaredFields();
for (Field field : fields) {
//属性
String fieldName = field.getName();
//setter方法名
String setterName = "set" + fieldName.substring(0, 1).toUpperCase()
+ fieldName.substring(1);
//getter方法名
String getterName = "get" + fieldName.substring(0, 1).toUpperCase()
+ fieldName.substring(1);
//获取setter方法
Method setterMethod = objClass.getMethod(setterName,
new Class[] { field.getType() });
//获取getter方法
Method getterMethod = objClass.getMethod(getterName,
new Class[] {});
//调用getter方法,得到传入的obj对象的属性值
Object fieldValue = getterMethod.invoke(obj);
//调用setter方法,设置objCopy对象的属性值为obj对象的属性值
setterMethod.invoke(objCopy, new Object[]{fieldValue});
}
return objCopy;
}
}
访问私有成员变量及方法
DemoPrivate类
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import com.test.reflect.User;
public class DemoPrivate {
public static void main(String[] args) throws Exception {
Class<?> userClass = Class.forName("com.test.reflect.User");
User user = (User) userClass.newInstance();
//访问私有方法,注:通过getDeclaredMethod()方法获取method对象,不能通过getMethod()方法
Method method = userClass.getDeclaredMethod("sayHello", String.class);
//压制Java对访问修饰符的检查
method.setAccessible(true);
String sayInfo = (String)method.invoke(user, "world");//hello,world
System.out.println(sayInfo);
//操作私有属性,注:通过getDeclaredField()方法获取method对象
Field field = userClass.getDeclaredField("name");
//压制Java对访问修饰符的检查
field.setAccessible(true);
field.set(user, "lily");
System.out.println(field.get(user));//lily
}
}