反射的应用
通过反射运行时获得类的完整结构
- 实现全部接口 Interface
- 继承的所有父类 SuperClass
- 全部的构造器 Constructor
- 全部的方法 Method
- 全部的属性 Field
- 注解 Annotation
@SuppressWarnings("rawtypes")
//压制警告,即去除警告
public class Reflection8 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, NoSuchMethodException {
// 通过反射运行时类的完整结构
//实现全部接口 Interface
//继承的所有父类 SuperClass
//全部的构造器 Constructor
//全部的方法 Method
//全部的属性 Field
//注解 Annotation
Class c1=Class.forName("reflection.User");
System.out.println(c1.getName()); //获得类名+包名
//System.out.println(c1.getCanonicalName());
System.out.println(c1.getSimpleName());//类名
//获得属性
Field[] field=c1.getFields();//只能找到 public属性
field=c1.getDeclaredFields();//找到所有属性
for (Field f:field) {
System.out.println(f);
}
//获得指定属性
Field name=c1.getDeclaredField("name");
System.out.println(name);
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
//获得方法
Method[] methods=c1.getMethods();//找 public
for(Method method:methods){
System.out.println("getMethods:"+method);
}
methods=c1.getDeclaredMethods();//找所有
for(Method method:methods){
System.out.println("getDeclaredMethods:"+method);
}
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
//获得指点方法
System.out.println(c1.getMethod("getName", null));
System.out.println(c1.getMethod("setName", String.class));
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
//获得构造器
Constructor[] construct =c1.getConstructors();
for(Constructor con:construct){
System.out.println(con);
}
construct =c1.getDeclaredConstructors();
for(Constructor con:construct){
System.out.println(con);
}
//找指定构造器
System.out.println("无惨"+c1.getConstructor(null));
System.out.println("有参"+c1.getConstructor(int.class,String.class,int.class));
}
}
获得了Class对象 然后能做什么
- 创建类的对象:调用Class对象的newInstance()方法
类必须有一个无参构造器
类的构造器的访问权限足够
- 当没有无参构造器时
通过Class类的getDeclaredConstructors()取的本类的指定形参类型的构造器
向构造器的形参传递一个对象数组进去,里面包含了构造器中所以的参数
通过Constructors()实例化对
- 通过反射调用普通方法
Object对应原方法的返回值,若原方法无返回值,次放回为null
若原方法为静态方法,此时行参Object可为null
若原方法形参列表为空,则Object[] args为null
若原方法声明为private,则需要在调用invoke()方法前,显示调用setAccessible(true)方法,将可访问privated的方法
public class Reflection9 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
// 获得了Class对象 然后能做什么
//创建类的对象:调用Class对象的newInstance()方法
//1.类必须有一个无参构造器
//2.类的构造器的访问权限足够
//
//1.通过Class类的getDeclaredConstructors()取的本类的指定形参类型的构造器
//2.向构造器的形参传递一个对象数组进去,里面包含了构造器中所以的参数
//通过Constructors()实例化对象
//创建类的对象
Class c1=Class.forName("reflection.User");
//构造一个对象
User user = (User)c1.newInstance();//调用了无参构造
System.out.println(user);
//通过构造器创建对象
Constructor constructor = c1.getConstructor(int.class,String.class,int.class);
user=(User) constructor.newInstance(111,"小明",23);
System.out.println(user);//改变了 构造器的参数
//通过反射调用普通方法
//调用指定的方法
//Object对应原方法的返回值,若原方法无返回值,次放回为null
//若原方法为静态方法,此时行参Object可为null
//若原方法形参列表为空,则Object[] args为null
//若原方法声明为private,则需要在调用invoke()方法前,显示调用setAccessible(true)方法,将可访问privated的方法
//invoke:激活 格式 (对象,方法值)
User user2 = (User)c1.newInstance();
Method setName = c1.getDeclaredMethod("setName", String.class);//拿到setName方法
setName.invoke(user2, "小明");//给setName方法传递值
System.out.println(user2.getName());//调用User类里的 getName方法,得到返回值
//通过反射 操作属性
User user3 = (User)c1.newInstance();
Field name = c1.getDeclaredField("name");
name.setAccessible(true);//关闭程序的安全检车
name.set(user3, "小军");
System.out.println(user3.getName());//在User类中的 所以属性都被设置为Private 要开启权限
}
}
反射操作泛型
- ParameterizedType:表示一种参数化类型,比如Collection
- GenericArrayType:表示一种元素类型是参数化类型或者类型变量的数组类型
- TypeVariable:是各种类型变量的公共接口
- WildcardType:表示一种通配符类型表达式
public class Reflection10 {
public void fun1(Map<String, User> map, List<User> list){
System.out.println("fun1");
}
public Map<String, User> fun2(){
System.out.println("fun1");
return null;
}
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException {
//反射操作泛型
//ParameterizedType:表示一种参数化类型,比如Collection<String>
//GenericArrayType:表示一种元素类型是参数化类型或者类型变量的数组类型
//TypeVariable:是各种类型变量的公共接口
//WildcardType:表示一种通配符类型表达式
Method method = Reflection10.class.getMethod("fun1",Map.class,List.class);
Type[] getGener = method.getGenericParameterTypes();//获得 范型的参数类型
for(Type getGeners:getGener){
System.out.println(getGeners);//打印 泛型
if(getGeners instanceof ParameterizedType){//判断getGeners是否是一个ParameterizedType参数化类型
Type[] TypeArguments = ((ParameterizedType)getGeners).getActualTypeArguments();
//获得真实参数信息
for(Type TypeArgument:TypeArguments){
System.out.println("!"+TypeArgument);
}
}
}
method = Reflection10.class.getMethod("fun2",null);
Type method1 = method.getGenericReturnType();//获得返回值 泛型
System.out.println(method1);//获得一个整体 泛型
if(method1 instanceof ParameterizedType){
Type[] method2 = ((ParameterizedType)method1).getActualTypeArguments();//获得一个具体泛型
for(Type method3:method2){
System.out.println("#"+method3);
}
}
}
}
通过反射操作 注解
public class Reflection11 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException {
//通过反射操作 注解
Class c1=Class.forName("reflection.Student1");
Annotation[] annotations = c1.getAnnotations();
for(Annotation annotation:annotations){
System.out.println(annotation);
}
//获得注解的 value的值
Myname myname = (Myname)c1.getAnnotation(Myname.class);//找到指定注解
String value = myname.value();//从中获得具体的值
System.out.println(value);
//获得指定注解
Field name=c1.getDeclaredField("id");//想要获取的 哪个属性
MyFiel fiel = name.getAnnotation(MyFiel.class);//获得 注解信息
System.out.println(fiel.columnName());
System.out.println(fiel.type());
System.out.println(fiel.length());
}
}
@Myname("是你吗?注解")
class Student1{
@MyFiel(columnName="id",type="int",length=8)
private int id;
@MyFiel(columnName="id",type="int",length=8)
private int age;
@MyFiel(columnName="id",type="varchar",length=8)
private String name;
public Student1() {
}
public Student1(int id, int age, String name) {
this.id = id;
this.age = age;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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;
}
public String toString() {
return "Student1 [id=" + id + ", age=" + age + ", name=" + name + "]";
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface Myname{
String value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface MyFiel{
String columnName();
String type();
int length();
}