对于私有的必须 getDeclaredField + setAccessible(true)
非public的,必须getDeclaredField
public,不限制
bean:
package three.day.reflect;
public class Teacher {
//private access
private String name;
//public access
public Integer age;
//protected access
protected String level;
//frinedly access
double salary;
public static String info = "xxx";
public Teacher(String name, Integer age, String level, double salary) {
super();
this.name = name;
this.age = age;
this.level = level;
this.salary = salary;
}
public Teacher(){
System.out.println("empty constructor invoked");
}
public Teacher(String name,Integer age){
this.name = name;
this.age = age;
System.out.println("Str Int constructor invoked" + " , " +
"name = " + this.name + " , age = " + this.age);
}
private static ThreadLocal<Teacher> threadLocal = new ThreadLocal<Teacher>();
public static Teacher getInstance(){
Teacher teacher = threadLocal.get();
if(teacher == null){
teacher = new Teacher();
threadLocal.set(teacher);
}
System.out.println("static method invoked");
return teacher;
}
private void privteMethod(){
System.out.println("privteMethod invoked");
}
protected void protectedMethod(){
System.out.println("protectedMethod invoked");
}
void friendlyMethod(){
System.out.println("friendlyMethod invoked");
}
//gettter and setter
public String getName() {
System.out.println("public method invoked");
return name;
}
public void setName(String name) {
System.out.println("public setName method invoked");
this.name = name;
}
public Integer getAge() {
System.out.println("public method invoked");
return age;
}
public void setAge(Integer age) {
System.out.println("public method invoked");
this.age = age;
}
public String getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Teacher [name=" + name + ", age=" + age + ", level=" + level
+ ", salary=" + salary + "]";
}
}
reflect:
package three.day.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
public class ReflectPerson {
public static void main(String[] args)
throws ClassNotFoundException, SecurityException, NoSuchMethodException,
IllegalArgumentException, InstantiationException, IllegalAccessException,
InvocationTargetException, NoSuchFieldException {
ClassLoader classLoader = ReflectPerson.class.getClassLoader();
System.out.println("1 classLoader = " + classLoader);
classLoader = Class.class.getClassLoader();
System.out.println("2 classLoader = " + classLoader);
classLoader = new ReflectPerson().getClass().getClassLoader();
System.out.println("3 classLoader = " + classLoader);
Class clazz = classLoader.loadClass("three.day.reflect.Teacher");
System.out.println("4 clazz = " + clazz);
clazz = Class.forName("three.day.reflect.Teacher");
System.out.println("5 clazz = " + clazz);
System.out.println("----------------start constructor----------------");
Constructor[] constructors = clazz.getConstructors();
int i = 6;
for(Constructor c : constructors){
System.out.println(i + " " + c);
i++;
}
Constructor cttEmpty = clazz.getConstructor(new Class[]{});
Object objEmpty = cttEmpty.newInstance(new Object[]{});
Constructor cttParamsStrInt = clazz.getConstructor(new Class[]{String.class,Integer.class});
Object objPramsStrint = cttParamsStrInt.newInstance(new Object[]{"lihuiming",45});
System.out.println("----------------end constructor----------------");
System.out.println("----------------start method----------------");
Method[] methods = clazz.getMethods();
for(Method m : methods){
System.out.println(m);
}
System.out.println("----------------------------------------------");
//----------------获取public静态方法 方法无参数---------------------------------------//
Method staticMethod = clazz.getDeclaredMethod("getInstance", new Class[]{});
staticMethod = clazz.getMethod("getInstance", new Class[]{});//访问权限是public的,所以调用该方法也可以
//调用方法
//静态方法 类型打点就可以访问,所以第一个参数可要可不要
staticMethod.invoke(null, new Object[]{});//会默认调用 public的参数的构造方法
//staticMethod.invoke(objEmpty, new Object[]{});
//下面对非静态方法进行测试,注意不同方法的访问权限
//访问权限为public的方法
Method setNameMethod = clazz.getMethod("setName", new Class[]{String.class});
setNameMethod = clazz.getDeclaredMethod("setName", new Class[]{String.class});
System.out.println("调用setName前 :" + objPramsStrint);
//非静态方法就需要知道是调用哪一个对象,这里第一个参数就是调用的是哪一个teacher的setName方法,第二个参数是调用方法的参数
setNameMethod.invoke(objPramsStrint, new Object[]{"zsoj"});
System.out.println("调用setName后 :" + objPramsStrint);
//对于其他访问权限为public的方法也是这样调用
//------------------------------------访问权限为protected-----------------------//
//方法无参数
//会报错: java.lang.NoSuchMethodException: three.day.reflect.Teacher.protectedMethod()
/*Method protectedMethod = clazz.getMethod("protectedMethod", new Class[]{});
protectedMethod.invoke(objPramsStrint, new Object[]{});*/
//会报错: java.lang.NoSuchMethodException: three.day.reflect.Teacher.protectedMethod()
/*Method protectedMethod = clazz.getMethod("protectedMethod", new Class[]{});
protectedMethod.setAccessible(true);
protectedMethod.invoke(objPramsStrint, new Object[]{});*/
//ok
Method protectedMethod = clazz.getDeclaredMethod("protectedMethod", new Class[]{});
//protectedMethod.setAccessible(true); //对于protected方法,这句可要可不要
protectedMethod.invoke(objPramsStrint, new Object[]{});
//------------------------------------访问权限为friendly-----------------------//
//方法无参数
//会报错: java.lang.NoSuchMethodException: three.day.reflect.Teacher.friendlyMethod()
/*Method friendlyMethod = clazz.getMethod("friendlyMethod", new Class[]{});
friendlyMethod.invoke(objPramsStrint, new Object[]{});*/
//会报错: java.lang.NoSuchMethodException: three.day.reflect.Teacher.friendlyMethod()
/*Method friendlyMethod = clazz.getMethod("friendlyMethod", new Class[]{});
friendlyMethod.setAccessible(true);
friendlyMethod.invoke(objPramsStrint, new Object[]{});*/
//ok
Method friendlyMethod = clazz.getDeclaredMethod("friendlyMethod", new Class[]{});
//friendlyMethod.setAccessible(true); //对于friendly方法,这句可要可不要
friendlyMethod.invoke(objPramsStrint, new Object[]{});
//------------------------------------访问权限为private-----------------------//
//方法无参数
//会报错: java.lang.NoSuchMethodException: three.day.reflect.Teacher.privteMethod()
/*Method privteMethod = clazz.getMethod("privteMethod", new Class[]{});
privteMethod.invoke(objPramsStrint, new Object[]{});*/
//会报错: java.lang.NoSuchMethodException: three.day.reflect.Teacher.privteMethod()
/*Method privteMethod = clazz.getMethod("privteMethod", new Class[]{});
privteMethod.setAccessible(true);
privteMethod.invoke(objPramsStrint, new Object[]{});*/
//ok
Method privteMethod = clazz.getDeclaredMethod("privteMethod", new Class[]{});
//没有这句会报错 :Class three.day.reflect.ReflectPerson can not access a member of class three.day.reflect.Teacher with modifiers "private"
privteMethod.setAccessible(true);
privteMethod.invoke(objPramsStrint, new Object[]{});
System.out.println("---------------------------end method--------------------------------");
//---------------------------------------------------------------------------------//
System.out.println("---------------------------start field--------------------------------");
Field[] fields = clazz.getDeclaredFields();
for(Field f : fields){
System.out.println(f);
}
System.out.println("---------------------------not declared----------------------------");
fields = clazz.getFields();
for(Field f : fields){
System.out.println(f);
}
//public static
Field infoField = clazz.getField("info");
infoField.set(objEmpty, "this is my info");
Object info = infoField.get(objEmpty);
System.out.println(info);
//public
Field ageField = clazz.getField("age");
System.out.println(ageField.getGenericType());
ageField.set(objEmpty, 55);
Object age = ageField.get(objEmpty);
System.out.println(age);
//protected
//报错 :Exception in thread "main" java.lang.NoSuchFieldException: level
/*Field levelField = clazz.getField("level");
levelField.set(objEmpty, "A");
Object level = levelField.get(objEmpty);
System.out.println(level);*/
Field levelField = clazz.getDeclaredField("level");
levelField.set(objEmpty, "A");
Object level = levelField.get(objEmpty);
System.out.println(level);
//friendly
Field salaryField = clazz.getDeclaredField("salary");
salaryField.set(objEmpty, 1000.00);
Object salary = salaryField.get(objEmpty);
System.out.println(salary);
//private
Field nameField = clazz.getDeclaredField("name");
nameField.setAccessible(true);
nameField.set(objEmpty, "xyz");
Object name = nameField.get(objEmpty);
System.out.println(name);
}
}