Java反射总结

目录

一、概述

二、反射与封装性

三、java.lang.Class的类的理解

1.获取Class的实例方式

2.Class不仅可以表示类,还可以表示其他它所学的类型。 

四、通过反射创建对应的运行时类的对象。

1.newInstance();调用此方法,创建对应的运行时类的对象。例:

2.反射的动态性

五、获取运行时类的完整结构

1.获取当前运行时类的属性结构

2.获取运行时类的方法结构

3.获取运行时类的构造器

4.获取运行时类的父类

5.获取运行时类的实现接口

6.获取运行时类所在的包

7.获取运行时类声明的注解

七.调用运行时类的指定结构

1.调用指定的结构

2.操作运行时类中指定的方法

3.指定的构造器


一、概述

Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期间借助于Reflection API获取到任何类的内部信息,并能直接操作任意对象的内部属性及方法。

二、反射与封装性

1.通过反射,可以调用类中私有构造器、私有方法、私有字段;也可以调用非私有的结构。在动态调用中使用反射。

2.反射与封装的矛盾

不矛盾,反射的初衷是为了调用类中公有的且是运行时类中的方法。

三、java.lang.Class的类的理解

加载到内存中国的类,称为运行时的类,此运行时的类就是class的一个实例。class的实例就对应一个运行时类。

1.获取Class的实例方式

①方式一:调用运行时类的名字.class

例:

Class clazz = Person.class;

②方式二:通过运行时类的对象,调用getClass()

Class clazz = P1.getClass;

③方式三:调用Class的静态方法:forName(String classPath)

Class clazz3 = Class.forName("com.ALi.java.Person");

④方式四:使用类的加载器ClassLoader(了解)

ClassLoader classloader = ReflectionTest.Class.getClassLoader();

classloader.loadClass("类的Path");

2.Class不仅可以表示类,还可以表示其他它所学的类型。 

数组中元素类型、维数一样它们的Class实例就相等。

四、通过反射创建对应的运行时类的对象。

1.newInstance();调用此方法,创建对应的运行时类的对象。
例:

Class clazz = Person.class;

Person obj = clazz.newInstance();

newInstance():

①内部调用运行时类的空参构造器。

②空参构造器的访问权限最小为缺省,通常设置为public。

在javaBean中要求提供一个public的空参构造器原因:

        1.便于通过反射,创建运行时类的对象

        2.便于子类继承此运行时类时,默认调用super()时,保证父类有此构造器。

2.反射的动态性

在代码运行时创建需要的对象。

五、获取运行时类的完整结构

1.获取当前运行时类的属性结构

Class clazz = Person.class();

Field[] f = clazz.getFields[];

①获取当前运行时类及其父类中声明为public访问权限的属性。

clazz.getDeclaredFields();

返回Field[]数组

②获取当前运行时类当中声明的所有属性(所有权限的属性都有),不含父类属性。

③获取属性权限 getModifiers()

Field[] fs = clazz.getDeclaredFields();
for(Field f :fs){
    int modifier = f.getModifiers();
    Modifier.toString(modifier);//将int数字转为对应的权限
}

④获取属性类型:getType()

class type = f.getType();

⑤获取变量名:getName()

String name = f.getName();

2.获取运行时类的方法结构

①获取父类中所有的public方法

getMethods();

返回值为Method[]

②获取当前运行时类的所有声明方法,不包含父类中声明的

getDeclaredMethods();

③获取方法的注解

getAnnotations();

for(Method m:declaredMethods){
    Annotation[] annos = m.getAnnotations();
    for(Annotation a:annos){
        System.out.println(a);
    }
}

④获取权限修饰符

getModifiers();

返回为int

Modifier.toString(int类型的权限修饰符);

⑤获取方法的返回值类型

m.getReturnType().getName();

⑥获取方法名

m.getName();

⑦获取形参列表

m.getParameterTypes();

⑧获取抛出的异常

m.getExceptionTypes();

3.获取运行时类的构造器

①获取当前运行时类中声明为public的构造器

clazz.getConstructors();

返回数组

②获取当前运行时类中声明的所有的构造器

clazz.getDeclaredConstructors(); 

4.获取运行时类的父类

①clazz.getSuperclass();返回Class类型

②获取带泛型的父类

Type superclass = clazz.getGenericSuperclass();

③获取带泛型的父类的泛型

Type s = clazz.getGenericSuperclass();
ParameterizedType p = (ParameterizedType)s;
Type[] ac = p.getActualTypeArguments();
ac[0].getTypeName();

5.获取运行时类的实现接口

class clazz = Person.class;
Class[] interfaces = clazz.getInterface();

②获取父类实现的接口

Class[] interface = clazz.getSuperclass().getInterface();

6.获取运行时类所在的包

Package ap = clazz.getPackage();

7.获取运行时类声明的注解

Annotation a[] = clazz.getAnnotations();

七.调用运行时类的指定结构

1.调用指定的结构

①指定的属性:属性为publi。

Field id = clazz.getDield("属性名");//通常不用该方法。

方式二:

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

Field name = clazz.getDeclaredFiedld("属性名");
name.setAccessible(true);
name.set(p,新值);
name.get(p);

②设置当前属性的值

id.set(p,100);

参数p为对象;参数100为此属性设置为多少。

③获取当前属性的值

int PID = (int) id.get(p);

2.操作运行时类中指定的方法

Class clazz = Person.class();
Person p = (Person)clazz.newInstance();
//获取某个指定的方法
Method show = clazz.getDeclaredMethod("方法名",参数的类);
show.setAccessible(true);

②方法名.invoke(对象,形参);

参数1:调用方法的对象

参数2:实参

show.invoke(p,"CHN");返回show方法的返回值

在静态方法中p可以写为null

3.指定的构造器

Class clazz = Person.class;

Constructor cc = clazz.getDeclaredConstructor(String.class);//获取指定的构造器,参数为形参类型。

//保证此构造器可以访问

cc.setAccessible(true);

//调用此构造器运行时类的对象

person p = cc.newInstance("Tom");//Tom为有参构造器中的参数.

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想进阿里的小菜鸡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值