反射

Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口

通过Class 能够获取类的信息,调用类的方法等。

一 生成Class对象

  

static Class<?> Class.forName(String className)
 className是类的全名
Class<?>

ClassLoader.loadClass(String name) name 是类的全名

ClassLoader来源:

1.Thread.currentThread().getContextClassLoader()

2.Class实例.getClassLoader() //Class对应的类最好不是jdk里的类

  3.ClassLoader.getSystemClassLoader()

 

直接引用 类名.class

 

类实例.getClass()

 

二 Class API

1.类型转换

  a. Integer i = (Integer)obj;//强制类型转换,需要写死在代码里

  b. Class类的方法: public T cast(Object obj) :

    Integer i =Integer.class.cast(obj);//将Object 转换为Integer类型

2. 类Annotation信息

 

  a.该Class对象代表的类是否标注了指定的Annotation

      public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {

  b.该Class对象代表的类是否标注了指定的Annotation,则返回该Annotation,否则返回 null。

    public <A extends Annotation> A getAnnotation(Class<A> annotationClass)

  c. 返回Class对象代表的类上标注的所有Annotation。

   public Annotation[] getAnnotations()     

 

 

3.从类路径上获取资源

  a.从类路径上获取指定名称的资源并返回它的输入流 ,name为资源的类路径全名,如/com/test/app/photo.jpg

        public InputStream getResourceAsStream(String name);                 

  b.从类路径上获取指定名称的资源,并返它的URL,name为资源的类路径全名,如/com/test/app/config.xml

     public java.net.URL getResource(String name);

 

4.判断Class表示的类的类型

    a.该Class对象代表的类是否是一个Annotation 

      public boolean isAnnotation() 

    b. 该Class对象代表的类是否是一个数组

     public  boolean isArray()

    c. 该Class对象代表的类是否是一个枚举

     public boolean isEnum()

    d. 该Class对象代表的类是否是一个接口

     public  boolean isInterface()

    e. 该Class对象代表的类是否是一个基本类型 (boolean、byte、char、short、int、long、float 和 double )+ void

       public  boolean isPrimitive();

   

5.获取类中内部类

  a.返回该Class对象代表的类及其父类中的所有public的内部类 

    public Class<?>[] getClasses()     

  b. 返回该Class对象代表的类中所有内部类(公共、保护、默认(包)访问及私有的内部类)(不含父类中的内部类)

    public Class<?>[] getDeclaredClasses()

    

6. 获取类的父类或接口

  a.返回该Class对象代表的类的实现的直接接口,带有泛型类型信息(接口可以有多个)

    public Type[] getGenericInterfaces()

    

  b.返回该Class对象代表的类的实现的直接接口  (接口可以有多个)

    public  Class<?>[] getInterfaces();

    

  c.返回该Class对象代表的类的扩展的直接父类,带有泛型类型信息(父类只有一个)

     public Type getGenericSuperclass()

     

  d. 返回该Class对象代表的类的扩展的直接父类  (父类只有一个)

     public  Class<? super T> getSuperclass()     

 

7.获取类中定义的泛型参数     

  public TypeVariable<Class<T>>[] getTypeParameters()

//System.out.println(Arrays.asList(List.class.getTypeParameters())); 输出为[E]即List定义时的泛型:public interface List<E>

8.数组类,获取其实例化时的类型

  public  Class<?> getComponentType()

  //Object [] objs = new String [5];

//Class classz = objs.getClass().getComponentType();

//System.out.println(classz.getName()); 输出为java.lang.String

9.获取类的构建器

  a.获取类的所有public的构建器

    public Constructor<?>[] getConstructors()

 

  b.根据构建器参数类型获取指定的public的构建器

     public Constructor<T> getConstructor(Class<?>... parameterTypes)

    

Constructor<String> constructor = String.class.getConstructor(String.class);
    System.out.println(constructor);
//输出:public java.lang.String(java.lang.String)
 c.获取类的所有构建器(含公共、保护、默认(包)访问和私有构建器及默认构建器 )

 

    public Constructor<?>[] getDeclaredConstructors()

 

 

 

d.根据构建器参数类型获取指定的构建器(可以是公共、保护、默认(包)访问和私有构建器及默认构建器 )

 

 

   public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)

   

 

10.获取类的属性

   a.获取类的所有public的属性

    public Field[] getFields()

 

  b.根据属性名称获取指定的public的属性

     public Field getField(String name)

 

  c.获取类的所有属性(含公共、保护、默认(包)访问和私有属性 ) 

    public Field[] getDeclaredFields()

 

d.根据属性名称获取指定的public的属性(可以是公共、保护、默认(包)访问和私有属性 )

 

  public Field getDeclaredField(String name)

 

11.获取类的方法

  a.获取类及父类的所有public的方法

      public Method[] getMethods()

 

  b.根据方法名及方法参数类型 从类或父类中获取指定的public的方法

     public Method getMethod(String name,Class<?>... parameterTypes)

 

  c.获取类及父类的所有的方法(含公共、保护、默认(包)访问和私有方法 )

    public Method[] getDeclaredMethods()

 

 

d.根据方法名及方法参数类型 从类或父类中获取指定的方法(可以是公共、保护、默认(包)访问和私有方法 )

public Method getDeclaredMethod(String name, Class<?>... parameterTypes)

 

 三 Constructor API

 

<T extends

Annotation>
T

getAnnotation(Class<T> annotationClass)
          如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。

         (含继承的Annotation)

 Annotation[] getDeclaredAnnotations()
          返回直接存在于此元素上的所有注释。
 Class<T> getDeclaringClass()
          返回此构建器所属的类的Class对象
 Class<?>[] getExceptionTypes()
       返回构建器方法,通过throws 声明的异常
 Type[] getGenericExceptionTypes()
        返回构建器方法,通过throws 声明的异常,带泛型信息
 Type[]

getGenericParameterTypes() 

返回构建器方法形参,带有泛型信息

 int getModifiers()
          以整数形式返回此 Constructor 对象所表示构造方法的 Java 语言修饰符。
 String getName()
          以字符串形式返回此构造方法的名称。
 Annotation[][] getParameterAnnotations()
         返回构建器方法的形参上的注释。
 Class<?>[] getParameterTypes()
          返回构建器方法形参,

 TypeVariable

<Constructor<T>>[]

getTypeParameters()
         返回构建器上的泛型声明
 int hashCode()
          返回此 Constructor 的哈希码。
 boolean isVarArgs()
          如果声明此构造方法可以带可变数量的参数,则返回 true;否则返回 false
 T newInstance(Object... initargs)
          使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。
 String toGenericString()
          返回描述此 Constructor 的字符串,其中包括类型参数。

 

 

四 Field API

 

 Object

get(Object obj)
          返回指定对象上此 Field 表示的字段的值。

 

User user = new User();
user.setName("xxx");
Object obj =User.class.getDeclaredField("name").get(user);
System.out.println(obj);//输出:xxx
 

 

 

它get方法:

 getXXX(Object obj )

 boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)
          如果指定类型的注释存在于此元素上,则返回 true,否则返回 false。(含继承来的Annotation)

<T extends

Annotation>
T

getAnnotation(Class<T> annotationClass)
          如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。

         (含继承的Annotation)

 Annotation[] getAnnotations()
          返回此元素上存在的所有注释。(含继承来的Annotation)
 Annotation[] getDeclaredAnnotations()
          返回直接存在于此元素上的所有注释。
 Class<?> getDeclaringClass()
          返回Filed所在类的Class对象
 Type getGenericType()
          返回一个 Type 对象,  它表示此 Field 对象所表示字段的声明类型。(带泛型)
 Class<?> getType()
          返回一个 Class 对象,它标识了此 Field 对象所表示字段的声明类型。
 int getModifiers()
          以整数形式返回由此 Field 对象表示的字段的 Java 语言修饰符。
 String getName()
          返回此 Field 对象表示的字段的名称。
 int hashCode()
          返回该 Field 的哈希码。
 boolean isEnumConstant()
          如果此字段表示枚举类型的元素,则返回 true;否则返回 false
 void set(Object obj, Object value)
          将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
 void

其它set方法:

setXXXX(Object obj,xxx类型值)

 

 String toGenericString()
          返回一个描述此 Field(包括其一般类型)的字符串。

 

 

 boolean isAccessible()
          获取此对象的 accessible 标志的值。
static void setAccessible(AccessibleObject[] array, boolean flag)
          使用单一安全性检查(为了提高效率)为一组对象设置 accessible 标志的便捷方法。
 void

setAccessible(boolean flag)
          将此对象的 accessible 标志设置为指示的布尔值。

 

 

 

五 Method API

 

 

<T extends Annotation>
T
getAnnotation(Class<T> annotationClass)
         返回该方法上的指定的Annotation (含继承)
 Annotation[] getDeclaredAnnotations()
         返回直接标注在该方法上的所有Annotation。
 Class<?>

getDeclaringClass()
          返回该方法所在的类对象

 Object getDefaultValue()
          如果该方法是Annotation的方法,返回由此 Method 实例表示的注释成员的默认值。
 Class<?>[]

getExceptionTypes()
        返回该方法通过 throws 声明的异常 

 Type[]

getGenericExceptionTypes()
           返回该方法通过 throws 声明的异常 ,带有泛形类型信息

 Type[] getGenericParameterTypes()
          返回该方法的形参类型数组,带泛形类型信息
 Type getGenericReturnType()
          返回表示由此 Method 对象所表示方法的正式返回类型的 Type 对象。
 int getModifiers()
          以整数形式返回此 Method 对象所表示方法的 Java 语言修饰符。
 String getName()
          以 String 形式返回此 Method 对象表示的方法名称。
 Annotation[][] getParameterAnnotations()
          返回表示按照声明顺序对此 Method 对象所表示方法的形参进行注释的那个数组的数组。
 Class<?>[] getParameterTypes()
        返回该方法的形参类型数组。
 Class<?> getReturnType()
          返回一个 Class 对象,该对象描述了此 Method 对象所表示的方法的正式返回类型。

 TypeVariable

<Method>[]

getTypeParameters()
         返回方法的泛形声明

          

public <T> T newInstace(Class<T> classz){
	return null;
}
			
TypeVariable<Method>[] tvs  = User.class.getMethod
("newInstace", Class.class).getTypeParameters();
for(int i=0;i<tvs.length;i++){
	TypeVariable tv = tvs[i];
	System.out.println(tvs[i]);//输出T
}

 

 int hashCode()
          返回此 Method 的哈希码。
 Object

invoke(Object obj, Object... args)
         调用该方法:obj 是对象实例,args是方法实参。

          静态方法obj参数为空

 boolean isVarArgs()
          如果将此方法声明为带有可变数量的参数,则返回 true;否则,返回 false
 String toGenericString()
          返回描述此 Method 的字符串,包括类型参数。

 

六 实例化类

  方式:

   a.构建器方法无参数的:Class.newInstance()

   b.构建器有参数的:通过参数类型获取构建器,再通过构建器生成类实例

                               Constructor constructor =    getDeclaredConstructor(Class<?>... parameterTypes);

 

                             constructor.newInstance(Object... initargs);

 

七 判断类实例是否为某个类或接口的实例

   a. 对象实例 instaceof 类A (需要在代码里写死)

        对象实例 是否是类A的实例或其子类的实例

   b. classA.isInstance(Object obj ) (可动态)

      对象实例obj  是否是classA的实例或其子类的实例

   c. classA.isAssignableFrom(Class classB) (可动态)

        classB是否是ClassA类或其子类

八 Array API:

static Object get(Object array, int index)
          返回指定数组对象中索引组件的值。
 

getXXX(Object array, int index)

返回指定数组对象中索引组件的值,并转换为xxx类型

static int getLength(Object array)
          以 int 形式返回指定数组对象的长度。
static Object newInstance(Class<?> componentType, int... dimensions)
          创建一个具有指定的组件类型和维度的新数组。
static Object newInstance(Class<?> componentType, int length)
          创建一个具有指定的组件类型和长度的新数组。
static void set(Object array, int index, Object value)
          将指定数组对象中索引组件的值设置为指定的新值。

 

	public void readArray(Object obj){
		if(obj.getClass().isArray()){
			int length = Array.getLength(obj);
			for(int index=0;index<length;index++){
				System.out.print(Array.get(obj, index));//输出0123456789
			}
		}
	}
	public Object createIntArray(int length) throws Exception{
		Object obj = Array.newInstance(Integer.class, length);
		for(int index=0;index<length;index++){
			Array.set(obj, index, index);
		}
		return obj;
	}
    
   调用:
   Object obj = createIntArray(10 );
  readArray(obj );

 

 

    

 

 九 BeanInfo 

 

对 JavaBean进行反射 

 

       Introspector API:

 

static BeanInfo

getBeanInfo(Class<?> beanClass)
          在 Java Bean 上进行内省,了解其所有属性、公开的方法和事件。

        ( 含父类)

  通获取JavaBean中的【public 类型  getXXXX()】方法,xxxx认为是属性,虽然有可能没有这个属性。(非public的方法获取不到)

static BeanInfo getBeanInfo(Class<?> beanClass, Class<?> stopClass)
          在给定的“断”点之下,在 Java Bean 上进行内省,了解其所有属性和公开的方法。     (对指定的父类(stopClass) 不进行内省

 

 

BeanInfo API:

 

 BeanDescriptor getBeanDescriptor()
          获得 beans BeanDescriptor
 MethodDescriptor[] getMethodDescriptors()
          获得 beans MethodDescriptor
 PropertyDescriptor[] getPropertyDescriptors()
          获得 beans PropertyDescriptor

 

             

 PropertyDescriptor API:

 

 Class<?> getPropertyType()
          获得属性的 Class 对象。
 Method getReadMethod()
          获得应该用于读取属性值的方法。
 Method getWriteMethod()
          获得应该用于写入属性值的方法。

 

MethodDescriptor API:

 Method getMethod()
          获得此 MethodDescriptor 封装的方法。
 ParameterDescriptor[] getParameterDescriptors()
          获得此 MethodDescriptor 每个方法参数的 ParameterDescriptor。

 

 

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;


public class UserBean {
	String name="ting";
	int age=20;
	String sex="female";

	public String getAddress(){//通过这个方法名,获取到Address属性,虽然这个属性不存在
		return null;
	}

	 String getName() {//获取不到Name属性,因为不是Public的
		return name;
	}
	 
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	public void setSex(String sex) {//获取不到Sex属性,因不没有getSex()方法
		this.sex = sex;
	}
	public static void main(String args []){
		try{
			BeanInfo beanInfo = Introspector.getBeanInfo(UserBean.class,Object.class);//object 类不进行内省,否则BeanInfo会多一些Object里的方法
			PropertyDescriptor propertyDescriptors [] = beanInfo.getPropertyDescriptors();//获取所有属性
			for(PropertyDescriptor pd :propertyDescriptors){//遍历
				String propertyName = pd.getName();//获取属性名
				Class type = pd.getPropertyType();//获取属性类型  
				Method readMethod = pd.getReadMethod();//获取读取方法 getXXXX()
				Method writeMethod = pd.getWriteMethod();//获取设置方法 setXXX( )
				
				if(readMethod != null ){
					UserBean userBean = new UserBean();
					Object obj = readMethod.invoke(userBean, null);//调用读取方法
					System.out.println(" propertyName="+propertyName+", class="+type+" ,currentValue="+obj);				//输出:
// propertyName=address, class=class java.lang.String ,currentValue=null
// propertyName=age, class=int ,currentValue=20
// propertyName=sex, class=class java.lang.String ,currentValue=female	
				}
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}

 

你可能感兴趣的:(反射)