反射——基本类周边信息获取

资料整理:

Java反射以及在Android中的使用

使用整理:

用反射执行方法示例:

public  void regex(对象 对象名) {
        if (null == 对象名) {
            return;
        }
        Method method;
        try {

            method = 对象.class.getDeclaredMethod("方法名",
                    参数类型.class);
            method.setAccessible(true);
            method.invoke(对象名, 参数);

        }
        catch (Exception e) {
            e.printStackTrace();
        }

    }

类的生命周期:

装载:类的装载是通过类加载器完成的,但是同一个类只会被类装载器装载一次,记住:只装载一次!利用装载的类可以实例化出各种不同的对象!

链接:链接就是把二进制数据组装为可以运行的状态。链接分为校验,准备,解析这3个阶段。校验一般用来确认此二进制文件是否适合当前的JVM(版本),准备就是为静态成员分配内存空间,并设置默认值。解析指的是转换常量池中的代码作为直接引用的过程,直到所有的符号引用都可以被运行程序使用(建立完整的对应关系)。

初始化:初始化就是对类中的变量进行初始化值;完成之后,类型也就完成了初始化,初始化之后类的对象就可以正常使用了,直到一个对象不再使用之后,将被垃圾回收。释放空间。
当没有任何引用指向Class对象时就会被卸载,结束类的生命周期。如果再次用到就再重新开始装载、链接和初始化的过程。

获取类类型:

类只会被装载一次,装载的类,我们称为类类型,利用装载的类产生的实例,我们称为类实例

//使用方法一
Class class1 = Animal.class;
System.out.println(class1.getName());
//使用方法二
Class<?> class2= Animal.class;
System.out.println(class2.getName());
泛型隐藏填充类型默认为无界通配符,所以上面的效果是一样的

获取类类型的四种方法:

//方法一:  Person person = new Person();  Class a = person.getClass()
//方法二: Class b = Persion.class;
//方法三: Class c = Class.forName(String ClassName); 
 //方法四:Class d = context.getClassLoader().loadClass(String ClassName);(不建议使用)

 这里的ClassName一定要从包名具体到类名,唯一定位到一个类才行,例如:com.example.myReflect.Animal

Class.forName有3个构造函数:

  • className:类名
  • initializeBoolean:表示是否需要初始化;如果设为true,表示在加载以后,还会进入链接阶段
  • classLoader:ClassLoader加载器

我们知道源文件在编译后,在运行时,分为三个阶段,加载,链接和初始化。这里的initializeBoolean就是定义是否进行链接和初始化。而Class.forName默认是设置的为true,所以利用Class.forName()得到的类类型,除了加载进来以外,还进行了链接和初始化操作。
Class.forName(String className)不仅会将类加载进来,而且会对其进行初始化,而ClassLoader.loadClass(String ClassName)则只是将类加载进来,而没有对类进行初始化。一般来讲,他们两个是通用的,但如果你加载类依赖初始化值的话,那ClassLoader.loadClass(String ClassName)将不再适用。

判断类的类型:

Class c = ArrayList.class;

c.isPrimitive(); //判断c是否为基本数据类型

c.isAssignableFrom(List.class); //判断c是否是List类的父类

例子:
Fragment.isAssignableFrom(xxx.class);

得到泛型类型:

Class c = ArrayList.class;

c.getGenericType(); //得到泛型类型

实例:通过反射得到List<T> 集合中的泛型类型

package com.zf.target;
 
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
 
class T{
	List<A>  a;
	List<B>  b;
//	List l ;
	Map<Integer, String> map ;
	int c;
}
 
class A {}
class B{}
 
public class Test9{
 
	public static void main(String[] args) {
		Class tc = T.class;
		Field[] fields = tc.getDeclaredFields();
		for (Field f : fields) {
			Class fc = f.getType();
			if(fc.isPrimitive()){
				System.out.println("基本数据类型: " + f.getName() + "  " + fc.getName());
			}else{
				if(fc.isAssignableFrom(List.class)){ //判断是否为List
					System.out.println("List类型:" + f.getName());
					Type gt = f.getGenericType();	//得到泛型类型
					ParameterizedType pt = (ParameterizedType)gt;
					Class lll = (Class)pt.getActualTypeArguments()[0];
					System.out.println("\t\t" + lll.getName());
				}
			}
		}
	}
	
}

实例化类的泛型为对象:

获取泛型的class对象
        Type genType = getClass().getGenericSuperclass();
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        Class<?> aClass = (Class) params[0];
通过class实例化对象
aClass.newInstance()

封装:
    public static <T> T getT(Class<?> cClass) {
        Type genType = cClass.getGenericSuperclass();
        T t = null;
        //如果泛型不等于Null
        if (!genType.getClass().getName().equals("java.lang.Class")) {
            Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
            Class<?> aClass = (Class) params[0];

            try {
                //实例化泛型
                t = (T) aClass.newInstance();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (java.lang.InstantiationException e) {
                e.printStackTrace();
            }
        }
        return t;
    }
Activity调用:
mPresenter = ObjectUtil.getT(this.getClass());
Fragment调用:
mPresenter = ObjectUtil.getT(BasesFragment.this.getClass());

类名,包名获取:

Class<?> class1 = Animal.class;
Package package1 = class1.getPackage();
Log.d(TAG,"完整的类名:"+class1.getName());
Log.d(TAG,"仅获取类名:"+class1.getSimpleName());
Log.d(TAG,"包名:"+package1.getName());

获取父类Class对象:

//获取普通函数的父类Class对象
public Class<?> getSuperclass();
//针对泛型父类而设计
public Type getGenericSuperclass();

示例:

Class<?> class2 = Class.forName("com.example.myReflect.AnimalImpl");
Class<?> parentClass = class2.getSuperclass();

获取类所直接继承的接口:

注意一点:直接继承,如果不是直接继承,那将获取不到

//获取普通接口的方法
public Class<?>[] getInterfaces();
//获取泛型接口的方法
public Type[] getGenericInterfaces();

示例:

Class<?> class3 = Animal.class;
Class<?>[] interfaces = class3.getInterfaces();
for (Class interItem : interfaces) {
 Log.d(TAG, "Animal继承的接口:" + interItem.getName());
}

获取类的访问修饰符:


Class<?> clazz = getClassLoader().loadClass(InnerClass.class.getName());
int modifiers = clazz.getModifiers();
String retval = Modifier.toString(modifiers);
boolean isFinal = Modifier.isFinal(modifiers);
Log.d(TAG, "InnerClass的定义修饰符:" + retval);
Log.d(TAG, "is Final:" + isFinal);

Modifier中主要有以下几个方法:
//根据整型变量来生成对应的修饰符字符串
String Modifier.toString(int modifiers) 
//以下这些方法来检查特定的修饰符是否存在
boolean Modifier.isAbstract(int modifiers)
boolean Modifier.isFinal(int modifiers)
boolean Modifier.isInterface(int modifiers)
boolean Modifier.isNative(int modifiers)
boolean Modifier.isPrivate(int modifiers)
boolean Modifier.isProtected(int modifiers)
boolean Modifier.isPublic(int modifiers)
boolean Modifier.isStatic(int modifiers)
boolean Modifier.isStrict(int modifiers)
boolean Modifier.isSynchronized(int modifiers)
boolean Modifier.isTransient(int modifiers)
boolean Modifier.isVolatile(int modifiers)

关于泛型信息如果获取:

参考文章:https://blog.csdn.net/harvic880925/article/details/50085595

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值