您的位置:首页 > 职场人生

黑马程序员---------Java反射(Reflection)笔记

2014-11-21 08:27 344 查看
-----------android培训java培训、java学习型技术博客、期待与您交流!------------ 

反射

反射相关的api:

Java.lang.Class:代表一个类

Java.lang.reflect.Method:代表类的方法

Java.lang.reflect.Field:代表类的成员变量

Java.lang.reflect.Constructor:代表类的构造方法

理解反射的源头之Class类:

我们创建了一个类,通过(javac.exe),生成对应的.class文件,之后,我们使用java.exe加载(JVM的类加载器)此.class文件,每个.class文件就是一个Class的实例。

 

如何获取Class的实例:

1:引用类的.class属性:

如:Class clazz=Person.class;

Class clazz2=String.class;

2:通过运行时类的getClass()方法获取:

Person p=new Person();

Class clazz3=p.getClass();

3:通过Class的静态方法.forName(String name)方法获取

必须指明完整报名,完整路径

Class clazz4=Class.forName("com.itheima.java.Person");

4:通过类加载器

ClassLoader loader=this.getClass().getClassLoader();

Class clazz5=loader.loadClass("com.itheima.java.Person");

 

ClassLoader类加载器掌握如下:

如何获取ClassLoader对象:

通过Class对象的getClassLoader()方法获得:

ClassLoader loader=this.getClass().getClassLoader();

分类:

引导类加载器:系统类库的加载器(如Object,String)(无法获得)

扩展类加载器:lib包中的扩展加载器

系统类加载器:用户自己开发的类的加载器

应用:获取项目包下的文件内容:

获取配置文件中的参数

ClassLoader loader2=this.getClass().getClassLoader();

InputStream is=loader2.getResourceAsStream("com\\itheima\\java\\jdbc.properties");

Properties per=new Properties();

per.load(is);

String name=per.getProperty("user");

String password=per.getProperty("password");

 

创建运行时类的对象:

Class clazz=Person.class;

//使用newInstance()方法实际上是调用了Person类的空参的构造方法

//Person类要有空参的构造器,构造器的权限要足够

Person p=(Person) clazz.newInstance();

 

获取运行时类的属性:

Class clazz=Person.class;

//获取运行时类及其父类中声明为public的属性

Field [] fields=clazz.getFields();

for(Field f:fields){

System.out.println(f.getName());

}

//获取运行时类中声明的属性

Field [] fields1=clazz.getDeclaredFields();

for(Field f:fields1){

System.out.println(f.getName());

}

获取属性的修饰符,类型

for(Field f:fields1){

//获取每个属性的修饰符

int i=f.getModifiers();

String str=Modifier.toString(i);

System.out.print(str);

//获取每个属性的类型

Class type=f.getType();

System.out.print(type.getName());

System.out.println();

}

 

获取运行时类的方法:

Class clazz=Person.class;

//获取运行时类及其父类中声明为public的方法

Method[] methods=clazz.getMethods();

for(Method m:methods){

System.out.println(m.getName());

}

//获取运行时类中本身声明的方法

Method[] methods1=clazz.getDeclaredMethods();

for(Method m:methods1){

System.out.println(m.getName());

}

获取方法的结构:

for(Method m:methods1){

//获取方法的注解annotation

Annotation[] ann=m.getAnnotations();

for(Annotation a:ann){

System.out.println(a);

}

//权限修饰符

String str=Modifier.toString(m.getModifiers());

System.out.print(str);

//返回值类型

Class returnType=m.getReturnType();

System.out.print(returnType.getName());

//方法名

System.out.print(m.getName());

//形参列表

Class[] para=m.getParameterTypes();

for(Class c:para){

System.out.print(c.getName());

}

}

获取父类:

Class clazz=Person.class;

Type type=clazz.getGenericSuperclass();

获取父类的泛型:

Type type=clazz.getGenericSuperclass();

System.out.println(type);

//强转为ParameterizedType子类对象

ParameterizedType pt=(ParameterizedType)type;

//获取泛型数组

Type[] types=pt.getActualTypeArguments();

 

调用运行时类的属性

Field name=clazz.getField("name");

Person p=(Person) clazz.newInstance();

name.set(p, "zhangsan");

调用声明为非public的属性

Field age=clazz.getDeclaredField("age");

age.setAccessible(true);

age.set(p, 12);

 

调用运行时类的方法

Class clazz=Person.class;

Method m=clazz.getMethod("show");

Person p=(Person) clazz.newInstance();

//invoke()方法的返回值既是原方法的返回值

m.invoke(p);

对于静态方法的调用

m.invoke(Person.class);

不用使用对象,直接使用类.class

调用修饰符为非public且有参数的方法

Method m1=clazz.getDeclaredMethod("display", String.class,Integer.class);

 m1.setAccessible(true);

 m1.invoke(p, "zhagnsan",20);

invoke()返回值既是原方法的返回值

 

调用有参且调用修饰符为非public的构造方法

Constructor con=clazz.getDeclaredConstructor(String.class,Integer.class);

 con.setAccessible(true);

 Person p2=(Person) con.newInstance("zhangsan",21);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: