反射就是解析对象,然后直接使用对象的东西,而不是通过变量去调用,反射比较消耗资源,有虚拟机规定,如果某个对象的反射使用的达到15次,就会将这个对象创建成具有反射特色的变量,方便直接调用其函数。
package Reflection;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.Repeatable;
@Documented
@Retention(RUNTIME)
@Target(TYPE)
@Inherited
@Repeatable(CustomDescriptions.class)
public @interface CustomDescription {
String description() default "";
}
package Reflection;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Documented
@Retention(RUNTIME)
@Target(TYPE)
@Inherited
public @interface CustomDescriptions {
CustomDescription[] value();
}
package Reflection;
@CustomDescription(description="基类")
@CustomDescription(description="人")
public class Person {
private String Name;
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public String PersonPublicMethod(String str)
{
return str;
}
public Person(String name) {
Name = name;
}
public String PersonPrivateMethod(String str)
{
return str;
}
public Person() {
super();
}
}
package Reflection;
@CustomDescription(description="学生")
@CustomDescription(description="人")
public class Student extends Person {
public String StudentId;
public String getStudentId() {
return StudentId;
}
public void setStudentId(String studentId) {
StudentId = studentId;
}
public String StudentPublicMethod(String str)
{
return str;
}
private String StudentPrivateMethod(String str)
{
return str;
}
public Student(String name, String studentId) {
super(name);
StudentId = studentId;
}
private Student(String name) {
super(name);
StudentId="123456";
}
public Student() {
}
}
##字符串例子
Class.Forname获取到对象。
Class clazz = null;
//类名.class
clazz = String.class;
System.out.println(clazz);
//对象.getClass()
clazz = "ReflectionTest".getClass();
System.out.println(clazz);
//Class.forName(全类名)
clazz = Class.forName("java.lang.String");
System.out.println(clazz);
Class clazz = Class.forName("包路径");//包路径,而不是.class,哈哈哈哈哈
Method method=null;
Method[] methods=null;
methods = clazz.getMethods();
for(Method mth:methods){
System.out.print(mth.getName()+" ");
}
System.out.println();
method = clazz.getMethod("StudentPublicMethod",String.class);
System.out.print(method.getName()+" ");
System.out.println();
methods = clazz.getDeclaredMethods();
for(Method mth:methods){
System.out.print(mth.getName()+" ");
}
System.out.println();
method = clazz.getDeclaredMethod("StudentPrivateMethod",String.class);
System.out.print(method.getName()+" ");
System.out.println();
Object obje = clazz.newInstance();
method.setAccessible(true);
String result=(String) method.invoke(obje,"inputParams");
System.out.println(result);
Class clazz = Class.forName("Reflection.Student");
// System.out.println("---------getDeclaredFields---------");
Field[] fields = clazz.getDeclaredFields();
for(Field field: fields){
System.out.print(field.getName()+" ");
}
System.out.println();
System.out.println("---------getFields---------");
fields = clazz.getFields();
for(Field field: fields){
System.out.print(field.getName()+" ");
}
System.out.println();
System.out.println("---------getDeclaredField---------");
Field field = clazz.getDeclaredField("StudentId");
field.setAccessible(true);
System.out.println(field.getName());
System.out.println("---------getField--------");
field = clazz.getField("StudentId");
System.out.println(field.getName());
Class clazz = Class.forName("Reflection.Person");
Person person = new Person("CYW");
//获取私有字段的值
Field field = clazz.getDeclaredField("Name");
//由于是私有字段,需要使用setAccessible(true)
field.setAccessible(true);
Object val = field.get(person);
System.out.println(val);
//改变私有字段的值
field.set(person, "ivan");
System.out.println(person.getName());
String className = "Reflection.Student";
// Class clazz = (Class) Class.forName(className);
//
// //指定成父类之后实际还是获取子类的构造函数
// Constructor [] constructors =
// (Constructor[]) Class.forName(className).getConstructors();
//
// for(Constructor constructor: constructors){
// System.out.println("getConstructors:"+constructor);
// }
//
// Constructor [] constructorsa =
// (Constructor[]) Class.forName(className).getDeclaredConstructors();
//
// for(Constructor constructor: constructorsa){
// System.out.println("getDeclaredConstructors:"+constructor);
// }
//
//
// //通过getConstructor获取公有构造函数
// Constructor constructor = clazz.getConstructor(String.class, String.class);
// System.out.println("getConstructor:"+constructor);
// Student obj = constructor.newInstance("cyw", "123456");
// System.out.println(obj.getName());
//
// //通过getDeclaredConstructor获取私有构造函数
// constructor = clazz.getDeclaredConstructor(String.class);
// System.out.println("getDeclaredConstructor:"+constructor);
// //对于私有构造函数在初始化之前要设置setAccessible(true)
// constructor.setAccessible(true);
// obj = constructor.newInstance("cyw");
// System.out.println(obj.getName());
String className = "Reflection.Student";
Class<Student> clazz = (Class<Student>) Class.forName(className);
CustomDescriptions customDescriptions =clazz.getAnnotation(CustomDescriptions.class);
for(CustomDescription h: customDescriptions.value()){
System.out.println("description:" + h.description());
//2.通过对象名
//这种方式是用在传进来一个对象,却不知道对象类型的时候使用
Person person = new Person();
clazz = person.getClass();
System.out.println(clazz);
//上面这个例子的意义不大,因为已经知道person类型是Person类,再这样写就没有必要了
//如果传进来是一个Object类,这种做法就是应该的
Object obj = new Person();
clazz = obj.getClass();
System.out.println(clazz);
//3.通过全类名(会抛出异常)
//一般框架开发中这种用的比较多,因为配置文件中一般配的都是全类名,通过这种方式可以得到Class实例
String className="Reflection.Person";
clazz = Class.forName(className);
System.out.println(clazz);