反射
一、反射:通过java的反射机制,可以在程序中访问已经装载到JVM中的java对象的描述,实现访问、检测和修改描述java对象本身信息的功能。java的反射机制功能非常强大,在java.long.reflect包中提供了对该功能的支持。
二、JAVA反射机制主要提供了以下功能:
*获取类的Class对象
获取类的Fields
获取类的Method
获取类的Constructor
新建类的实例
Class的函数newInstance
通过Constructor对象的方法newInstance*
三、 Java 反射相关的API简介:
位于java.lang.reflect包中
–Class类:代表一个类
格式: Class 对象=类名.class;
Class clazz=Stu.class;//得到Stu类的class的对象
public class Test {
public static void main(String[] args) {
Class<Stu> clazz=Stu.class;// class格式: 类 Class<T>
Field[] fields=clazz.getDeclaredFields();
// for(Field field:fields){//类型为Field
// System.out.println(field.getName());
// System.out.println(field.getType());
// System.out.println(field.getModifiers());
// }
Stu zhangsan=new Stu();
try {
Field age=clazz.getDeclaredField("age");
age.setAccessible(true);
age.set(zhangsan, 18);
age.setAccessible(false);
System.out.println(zhangsan.getAge());
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
--Filed类:代表类的成员变量
格式:Field[] 成员变量=对象.getDeclaredField();
Field field = clazz.getDeclaredField();
–Method类:代表类的方法,返回Method类型的对象或数组
格式:Method[] 方法=对象.getDeclaredMethod();
Method[] method=clazz.getDeclaredMethod();
–Constructor类:代表类的构造方法
格式:Constructor[] 构造=对象.getDeclaredConstructor();
Constructor[] con=clazz.getDeclaredConstructor();
相关代码
注解
JDK1.5开始增加了Annotation功能,该功能可以用于类、构造方法、成员变量、方法、参数等的声明中。
在定义Annotation类型时,也需要用到用来定义接口的interface关键字,但需要在interface关键字前加一个”@“符号。
用法:
建一个Annotation类型的java文件
在该文件中注解要注解的内容。
写class文件,写属性,并加上注解,在构造器中进行相关操作
{Class
Field
Annotion an=(field).getAnnotation(rAnnotion.class)
对象的age、name
输出
}
用法实例:
一、
Teacher文件
TeacherAnnotation文件
Clazz文件
测试文件
package fanshe;
public class Teacher extends Person{
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package fanshe;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)//注意此处为.而不是,
//表示此注解的范围是可执行的
@Target(ElementType.FIELD)//表示此注解只能用在属性上
public @interface TeacherAnnotion {
int age() default 19;
//表明此处可以注解一个int值,当age值为null时,默认为19
String name();
}
package fanshe;
import java.lang.reflect.Field;
public class Clazz {
@TeacherAnnotion(age=19,name="zhangsan")
private Teacher engilshteacher;//Teacher类型的老师
@TeacherAnnotion(age=20,name="李四")
private Teacher mathtcher;
@TeacherAnnotion(name="王五")
private Teacher javatacher;
private int classnum;
public Clazz(){
//在构造器中初始化成员变量
Class clazz=Clazz.class;
Field[] field=clazz.getDeclaredFields();
for(Field file:field){
TeacherAnnotion an=file.getAnnotation(TeacherAnnotion.class);
//得到注解内容
if(an==null){
}else{
int age=an.age();
String name=an.name();
Teacher teacher=new Teacher();//创建对象
teacher.setAge(age);
teacher.setName(name);
file.setAccessible(true);//私有变量可访问
try {
file.set(this, teacher);
//set(Object obj, Object value)
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
file.setAccessible(false);//私有变量不可访问
}
}
}
public Teacher getEngilshteacher() {
return engilshteacher;
}
public void setEngilshteacher(Teacher engilshteacher) {
this.engilshteacher = engilshteacher;
}
public Teacher getMathtcher() {
return mathtcher;
}
public void setMathtcher(Teacher mathtcher) {
this.mathtcher = mathtcher;
}
public Teacher getJavatacher() {
return javatacher;
}
public void setJavatacher(Teacher javatacher) {
this.javatacher = javatacher;
}
}
package fanshe;
public class Testanteacher {
public static void main(String[] args) {
Clazz clazz=new Clazz();
System.out.println(clazz.getEngilshteacher().getName()+clazz.getEngilshteacher().getAge());
}
}
二、
package fanshe;
import java.lang.reflect.Field;
public class Stu extends Person{
@StudentAnotation(18)
private int age;
public Stu(){
Class clazz=Stu.class;//得到Stu类的class的对象
Field field;
try {
field = clazz.getDeclaredField("age");
field.setAccessible(false);StudentAnotation sa=field.getAnnotation(StudentAnotation.class);
if(sa!=null){
int i=sa.value();//得到属性默认值
field.setAccessible(true);//设置为不检查属性的访问修饰符
field.set(this, i);//this指的是stu的对象
//将stu的对象的age属性修改为1
// field.setAccessible(false);StudentAnotation sa=field.getAnnotation(StudentAnotation.class);
}
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch blockfield.setAccessible(false);StudentAnotation sa=field.getAnnotation(StudentAnotation.class);field.setAccessible(false);StudentAnotation sa=field.getAnnotation(StudentAnotation.class);
e.printStackTrace();
}//得到对象的age属性
// StudentAnotation sa=field.getAnnotation(StudentAnotation.class);
//得到age属性的StudentAnnotation注解,如果没有,返回null
catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private String name;
public String sex;
public String aihao;
public int getAge() {
return age;
}
// public void setAge(int age) {
// this.age = age;
// }
@Override //这个方法是复写父类的方法
public void sleep(){
System.out.println("学生在睡觉");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
反射代码补充
初学时写的Test
package fanshe;
import java.lang.reflect.Field;
public class Test {
public static void main(String[] args) {
Class<Stu> clazz=Stu.class;// class格式: 类 Class<T>
Field[] fields=clazz.getDeclaredFields();
// for(Field field:fields){//类型为Field
// System.out.println(field.getName());
// System.out.println(field.getType());
// System.out.println(field.getModifiers());
// }
//
Stu zhangsan=new Stu();
try {
Field age=clazz.getDeclaredField("age");
age.setAccessible(true);
age.set(zhangsan, 18);
age.setAccessible(false);
System.out.println(zhangsan.getAge());
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Person文件
package fanshe;
public class Person {
public void sleep(){
System.out.println("人在睡觉");
}
}
Stu文件
package fanshe;
import java.lang.reflect.Field;
public class Stu extends Person{
@StudentAnotation(18)
private int age;
public Stu(){
Class clazz=Stu.class;//得到Stu类的class的对象
Field field;
try {
field = clazz.getDeclaredField("age");
field.setAccessible(false);StudentAnotation sa=field.getAnnotation(StudentAnotation.class);
if(sa!=null){
int i=sa.value();//得到属性默认值
field.setAccessible(true);//设置为不检查属性的访问修饰符
field.set(this, i);//this指的是stu的对象
//将stu的对象的age属性修改为1
// field.setAccessible(false);StudentAnotation sa=field.getAnnotation(StudentAnotation.class);
}
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch blockfield.setAccessible(false);StudentAnotation sa=field.getAnnotation(StudentAnotation.class);field.setAccessible(false);StudentAnotation sa=field.getAnnotation(StudentAnotation.class);
e.printStackTrace();
}//得到对象的age属性
// StudentAnotation sa=field.getAnnotation(StudentAnotation.class);
//得到age属性的StudentAnnotation注解,如果没有,返回null
catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private String name;
public String sex;
public String aihao;
public int getAge() {
return age;
}
// public void setAge(int age) {
// this.age = age;
// }
@Override //这个方法是复写父类的方法
public void sleep(){
System.out.println("学生在睡觉");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
clazz=fanshe.Person
Factory文件
package fanshe;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
public class Factory {
public static Person Creatperson(){
Person person=null;
Properties p=new Properties();
//Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串
try {
p.load(new FileInputStream("config.properties"));//从输入流中读取属性列表(键和元素对)。
String clazzname=p.getProperty("clazz");
//clazzname="clazz"
Class clazz=Class.forName(clazzname);
//类似于通过key值的value clazz=fanshe.Person
person=(Person) clazz.newInstance();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
};
return person;
}
}
Factorytest文件
package fanshe;
public class Factorytest {
public static void main(String[] args) {
Person person=Factory.Creatperson();
person.sleep();
}
}