Java反射基础知识

反射基础知识:

Java.lang.Class是所有类对象的定义类,同时是所有反射的入口.
Java的安全框架:Java.Security
Java.security.Permission
在这里插入图片描述
反射会打破OOP对象/类的封装.Java中所有类型不一定是对象,然而每种类型都是类对象(java.lang.class)
java类型:
对象类型(java.lang.Object子类) -> java.lang.Object.class
数组类型([]) -> xxx[].class
原生类型(int等) -> int.class
特殊类型(Void 仅在方法返回类型中) -> Void.class
反射性能:(性能优化)!!! AccessibleObject是Field,Method,Construct的父类,默认情况下,任何AccessObject对象都会做访问性检查,因此关闭此检查可以提升性能.setAccessible(false);

反射核心组件

类对象

  1. 类(Classes):java.lang.Object.class
  2. 接口(Interfaces):java.lang.CharSequence.class
  3. 枚举(Enums):java.util.concurrent.TimeUnit.class: 枚举它是特殊的类 enum xxx = final class xxx extends java.lang.Enum
    字段常量(Constants)
    内建行为(Build-in Behaviors)Values()方法 -> 编译器帮助我们生成的方法
    合成的父类(java.lang.Enum)
    枚举的CompareTo()方法
public final int compareTo(E o) {
	 Enum<?> other = (Enum<?>)o;
	 Enum<E> self = this;
	if (self.getClass() != other.getClass() && // optimization
 			self.getDeclaringClass() != other.getDeclaringClass())
		throw new ClassCastException();
	 return self.ordinal - other.ordinal;
}

只是比较类是否相同,以及字段常量的位置是否相同.不会比较内容是否相同.

  1. 注解(Annotation):java.lang.Override.class -> 特殊的接口 @interface TestAnnotation = public interface TestAnnotation extends java.lang.Annotation
    属性方法(Attributes)
    内建行为(Build-in Behaviors)
    合成的接口(java.lang.annotation.Annotation)
			@Documented 
			@Target(CONSTRUCTOR) 
			@Retention(RUNTIME)
			public @interface ConstructorProperties {
			    /**
			       <p>The getter names.</p>
			       @return the getter names corresponding to the parameters in the
			       annotated constructor.
			    */
			    String[] value(); // -> 属性方法
			}
  1. 原生类型(primitives):int.class
		 public static void main(String[] args) {
		        //具体类对象
		        System.out.println(!Modifier.isAbstract(Object.class.getModifiers()));
		        //抽象类对象
		        System.out.println(Modifier.isAbstract(AbstractList.class.getModifiers()));
		        //接口类对象
		        System.out.println(Serializable.class.isInterface());
		        //枚举类对象
		        System.out.println(FileVisitOption.class.isEnum());
		        //注解类对象
		        System.out.println(Nullable.class.isAnnotation());
		        //数组类对象
		        System.out.println(int[].class.isArray());
		        //原生类对象
		        System.out.println(int.class.isPrimitive());
		    }

泛型

  1. 泛型信息(Generics Info):泛型参数(Parameters),泛型父类(Super Classes),泛型接口(Interfaces)
		public static void main(String[] args) {
		        List<Integer> values = Arrays.asList(1,2,3);
		        System.out.println(values.getClass().toGenericString());
		}
		private static class java.util.Arrays$ArrayList<E>

泛型信息(Generics info):java.lang.Class#getGenericInfo();
泛型参数(Parameters):java.lang.reflect.ParameterizedType() //-> 这个是带有泛型参数的类型!
泛型父类(Super Classes):java.lang.Class#getGenericSuperclass()
泛型接口(Interfaces):java.lang.Class#getGenericInterfaces();
泛型申明(Generics Declaration):java.lang.reflect.GenericDeclaration

  1. 泛型擦写(Generics Erase)
		 public static void main(String[] args) {
		        System.out.println(StringList.class.getSuperclass().toGenericString());
		    
		}
		class StringList extends ArrayList<String>{
		
		}
		输出结果:
		public class java.util.ArrayList<E>
		
		public static void main(String[] args) {
		        System.out.println(StringList.class.getGenericSuperclass().toString());
		    
		}
		class StringList extends ArrayList<String>{
		
		}
		输出结果:
		java.util.ArrayList<java.lang.String>

以上的举例其实就是想说明一点:泛型其实在编译的时候,类型还是会被保存在字节码文件当中,但是当运行的时候类型就会被擦写掉了,object类型的都是可以插入的.


		public class StringDemo {
		    public static void main(String[] args) throws Exception {
		        //类所在的classpath物理路径
		        /*System.out.println(scanBasePackageClass.getProtectionDomain());
		        System.out.println("==============");
		        System.out.println(scanBasePackageClass.getProtectionDomain().getPermissions());
		        System.out.println("==============");
		        System.out.println(scanBasePackageClass.getProtectionDomain().getCodeSource());
		        System.out.println("==============");
		        System.out.println(scanBasePackageClass.getProtectionDomain().getCodeSource().getLocation());*/
		
		        // 模仿 Spring 类扫描
		        // 通过标准方式 - Java 反射
		        // 通过 ASM -
		
		        Class<?> scanBasePackageClass = StringDemo.class;
		        String scanBasePackage = scanBasePackageClass.getPackage().getName();
		        // 类所在的 class path 物理路径
		        String classPath = getClassPath(scanBasePackageClass);
		        File classPathDirectory = new File(classPath);
		        File scanBasePackageDirectory = new File(classPathDirectory, scanBasePackage.replace('.', '/'));
		        // 获取所有的 Class 文件 -> *.class
		        File[] classFiles = scanBasePackageDirectory.listFiles(file -> {
		            return file.isFile() && file.getName().endsWith(".class");
		        });
		        System.out.println("class path : " + classPath);
		        System.out.println("scan base package : " + scanBasePackage);
		        System.out.println("scan class files :" + Stream.of(classFiles).map(File::getName).collect(Collectors.joining(",")));
		
		        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
		
		        List<Class<?>> targetClasses = new LinkedList<>();
		        for (File classFile : classFiles) {
		            String simpleClassName = classFile.getName().substring(0, classFile.getName().lastIndexOf("."));
		            String className = scanBasePackage + "." + simpleClassName;
		            // 加载所有类
		            Class<?> loadedClass = classLoader.loadClass(className);
		            // 判断是否存在 @Repository 注解
		            if (loadedClass.isAnnotationPresent(Repository.class)) {
		                targetClasses.add(loadedClass);
		            }
		        }
		
		        // 判断 targetClasses 是否 CrudRepository 类的实现类
		
		        targetClasses.stream()
		                .filter(StringDemo::isConcrete) // 筛选具体类
		                .filter(StringDemo::isCrudRepositoryType) // 筛选 CrudRepository 类的实现类
		                .forEach(type -> { // CrudRepository 泛型类型
		                    Type[] superInterfaces = type.getGenericInterfaces(); // 获取泛型父接口
		                    Stream.of(superInterfaces)
		                            .filter(t -> t instanceof ParameterizedType)// 判断接口是否 ParameterizedType 类型
		                            .map(t -> (ParameterizedType) t)             //  转换为 ParameterizedType
		                            .filter(parameterizedType -> CrudRepository.class.equals(parameterizedType.getRawType())) // 判断 ParameterizedType 原始类型是否 CrudRepository
		                            .forEach(parameterizedType -> {
		                                // 获取第一个泛型参数
		                                String argumentTypeName = parameterizedType.getActualTypeArguments()[0].getTypeName();
		                                try {
		                                    System.out.println(classLoader.loadClass(argumentTypeName));
		                                } catch (ClassNotFoundException e) {
		                                    e.printStackTrace();
		                                }
		                            });
		                });
		    }
		
		    private static boolean isCrudRepositoryType(Class<?> type) {
		        return CrudRepository.class.isAssignableFrom(type);
		    }
		
		    private static boolean isConcrete(Class<?> type) {
		        return !Modifier.isAbstract(type.getModifiers());
		    }
		
		    private static String getClassPath(Class type) {
		        return type.getProtectionDomain().getCodeSource().getLocation().getPath().substring(1);
		    }
		}
		
		
		interface CrudRepository<E extends Serializable> {
		
		    // declared methods...
		
		}
		
		
		@Repository
		class UserRepository implements Comparable<UserRepository>, // getGenericInterfaces[0] = ParameterizedType ->
		                                                            // ParameterizedType.rawType = Comparable
		                                                            // ParameterizedType.getActualTypeArguments()[0] = UserRepository
		
		        CrudRepository<User>,      // getGenericInterfaces[1] = ParameterizedType -> ParameterizedType.rawType = CrudRepository
		                                    // ParameterizedType.rawType = CrudRepository
		                                    // ParameterizedType.getActualTypeArguments()[0] = User
		
		        Serializable {             // getGenericInterfaces[2] = Class -> isInterface() == true
		
		    @Override
		    public int compareTo(UserRepository o) {
		        return 0;
		    }
		}
		
		@Target(ElementType.TYPE)
		@Retention(RetentionPolicy.RUNTIME)
		@interface Repository {
		
		    String value() default "";
		}
		
		
		class User implements Serializable {
		
		    private String name;
		
		    private int age;
		
		    public String getName() {
		        return name;
		    }
		
		    public void setName(String name) {
		        this.name = name;
		    }
}

类成员

  1. 字段(字段本身是元数据,包含的内容是数据或称为属性)
    类字段
    对象字段
  2. 方法(Methods)(描述对象行为的契约或者实现)方法唯一约束是方法签名
    归属(定义所在)
    访问修饰符(public)
    访问性(Accessibility):public protected private
    属性:
static final volatile transient//(反持久化的)
Private transient int hashCode;//(缓存hashCode)配合serializable -> 属性不会被序列化
Private static trasient int hashCode; //这个是没有意义的,因为static是跟着类走的,类是决定结构的 -> static就是transient.序列化和反序列化都是跟着对象走的
//方法:
static final synchronize native abstract strictfp
Strictfp float add(float a , float b){
	Return a+b;
}
`返回类型(Return type)`
`方法名称(method name)`
`方法参数(method parameters)`
`方法异常列表(method throws)`
  1. 构造器(Constructors)
    归属(定义所在)
    访问修饰符(public)
    构造器名称(construct name = Class Names)
    构造器参数(construct parameters)
    构造器异常列表(method throws)
  2. 成员(Members):java.lang.reflect.Members
  3. 可执行成员(Executable):java.lang.reflect.Executable(Java8新增的内容)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值