-
Class类与Java反射
通过下列一组方法访问构造方法时,将返回Constructor类型的对象或数组。每个Constructor对象代表一个构造方法,利用Constructor对象可以操纵相应的构造方法
- getConstructors()
- getConstructor(Class<?>... parameterTypes)
- getDeclaredConstructors()
- getDeclaredConstructor(Class<?>... parameterTypes)
如果是访问指定的构造方法,需要根据该构造方法的入口参数的类型来访问。
package com.example.java;
public class Example_01 {
String s;
int i,i2,i3;
/*构造方法(构造函数)
* 有参构造
*
* 无参构造
*
* 类名与构造方法名相同
*
* 同一类中先执行有参构造再执行无参构造,子类继承父类执行顺序:父类无参数构造》子类无参构造》父类有参数构造》子类无参构造
*
* */
private Example_01(){
/*访问修饰符:
* private 私有控制访问符 被修饰的成员变量仅能被自身访问
* public 公共访问控制符 所有类都可以访问,但会降低运行安全性和数据的封装性,谨慎使用
* protected 保护访问控制符 主要是供子类引用,同一包中的其他类也可引用
* default 缺省默认访问符 没有定义成员变量的修饰符默认为default,可以被本类或同一包中的其他类访问
*
* 非访问修饰符
* static 静态域修饰符 用static修饰的成员变量仅属于本类的变量,而不属于任何一个具体对象,
* static修饰的成员变量保存在类的公共存储单元,该类任何对象访问它是获取的数据都市相同的,
* 该类的任何对象修改它是,都是对同一内存单元进行操作
* final 最终域修饰符 修饰常量 被它修饰的常量在运行过程中常量的值不可再该变
* volatile 共享(易失)域修饰符 被它修饰的成员变量可能被几个线程控制和修改,一般用来修饰可接受外部输入的域
* transient 暂时性域修饰符 修饰暂时性变量
* */
}
protected Example_01(String...strings) throws NumberFormatException{
//String...strings 定义可变长度的数组
if(0<strings.length)
i=Integer.valueOf(strings[0]);
//Integer类提供了两种构造方法:它们都会返回一个Integer对象
if(1<strings.length)
i2=Integer.valueOf(strings[1]);
if(2<strings.length)
i3=Integer.valueOf(strings[2]);
}
public void print(){
System.out.println("s="+s);
System.out.println("i="+i);
System.out.println("i2="+i2);
System.out.println("23="+i3);
}
}
MAIN类
package com.example.java;
import java.lang.reflect.Constructor;
public class Main_01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//调用Example_01()方法
Example_01 example = new Example_01("10","20","30");
//访问构造方法
Class<? extends Example_01> exampleC=example.getClass();
//返回Constructor对象的数组,这些对象反映此Class
Constructor[] declaredConstructors =exampleC.getDeclaredConstructors();
//遍历Constructor对象的数组
for(int i=0;i<declaredConstructors.length;i++){
Constructor<?> constructor=declaredConstructors[i];
System.out.println("查看是否允许带有可变数量的参数"+constructor.isVarArgs());
System.out.println("该构造方法的入口参数类型依次为:");
/*java.lang.reflect.Constructor.getParameter();方法返回一个Class对象数组,它以声明顺序表示由此构造方对象表示的构造函数的形式参数类型。
* 如果底层构造函数没有参数,则返回长度为0的数组。
* 返回值:此对象表示的构造函数的参数类型。
* */
Class[] parameterTypes =constructor.getParameterTypes();
//循环遍历数组
for(int j=0;j<parameterTypes.length;i++){
System.out.println(""+parameterTypes[j]);
}
System.out.println("该构造方法可能抛出异常的类型为:");
/*java.lang.reflect.Constructor.getExceptionTypes()方法返回一个Class对象数组,
* 该对象表示由此构造方对象表示的底层构造函数声明的异常类型。
* 如果构造函数在其throws子句中声明没有异常,则返回一个长度为0的数组。
*
* 返回值:声明为由此对象表示的构造函数抛出的异常类型。
* */
Class[] exceptionTypes =constructor.getExceptionTypes();
//遍历数组
for(int j=0;j<exceptionTypes.length;j++){
}
Example_01 example2 =null;
while(example2 ==null){
try{
if(i ==2)
//创建对象newInstance(); 使用类加载机制创建对象 只能调用无参构造 执行效率低
example2 =(Example_01) constructor.newInstance();
else if(i==1)
example2 =(Example_01)constructor.newInstance("7",5);
else{
Object[] parameters =new Object[]{new String[]{
"100","200","300"}};
}
}catch(Exception e){
System.out.println("在创建对象时抛出异常,下面执行setAccessible()方法");
constructor.setAccessible(true);
}
}
if(example2!=null){
example2.print();
System.out.println();
}
}
}
}
- 访问成员变量
通过下列一组方法访问成员变量时,将返回Field类型的对象或数组。每个Field对象代表一个成员变量,利用Field对象可以操纵相应的成员变量。
- getFields()
- getField(String name)
- getDeclaredFields()
- getDeclaredField(String name)
- 访问方法
通过下列一组方法访问方法时,将返回Method类型的对象或数组。每个Method对象代表一个方法,利用Method对象可以操纵相应的方法
- getMethods()
- getMethod(String name, Class<?>... parameterTypes)
- getDeclaredMethods()
- getDeclaredMethod(String name, Class<?>... parameterTypes)
如果是访问指定的方法,需要根据该方法的名称和入口参数的类型来访问。
-
使用Annotation的功能
- 定义Annotation类型
- 在定义Annotation类型时,需用定义接口的interface关键字,要在interface关键字前加一个“@”符号,即定义Annotation类型的关键字为@interface,这个关键字的隐含意思是继承了java.lang.annotation.Annotation接口。
- 访问Annotation信息
- 在定义Annotation类型时将@Retention设置为RetentionPolicy.RUNTIME,那么在运行程序时通过反射就可以获取到相关的Annotation信息,如获取构造方法、字段和方法的Annotation信息。
- 类Constructor、Field和Method均继承了AccessibleObject类
- isAnnotationPresent(Class<? extends Annotation> annotationClass)用来查看是否添加了指定类型的Annotation,如果是则返回true,否则返回false;
- 法getAnnotation(Class<T> annotationClass)用来获得指定类型的Annotation,如果存在则返回相应的对象,否则返回null;
- 方法getAnnotations()用来获得所有的Annotation,该方法将返回一个Annotation数组。