反射的相关概念
1.清除封装-将域设置成私有的,而后提供相对应的set和get方法来操做这个域。可是咱们能够经过Java的反射机制来修改类的私有域。
主要技术:
Field类提供有关类或接口的单个字段的信息,以及它的动态访问权限。
访问的字段多是一个类(静态)字段或实例字段。
经常使用方法:
set(Object obj,Object value).
2.动态调用类
能够根据须要指定要调用的方法,而没必要在编程时肯定。调用的方法不只权限于public的,还能够是private。
Method类提供类或接口上单独某个方法的信息,所反映的方法是类方法或实例方法(包括抽象方法)。它容许在匹配调用的时候实参于底层方法的形参时进行扩辗转换,
可是若是要进行收缩转换,则会抛出“非法参数异常”。
使用invoke()。
public Object invoke(Object obj,Object...args)throws IllegalArgumentException,IllegalAccessException,InvocationTargetExcetion
obj--要调用的方法的类对象
args--方法调用的参数 java
Method meth = Math.class.getDeclaredMethod("abs", Integer.TYPE);
Integer a = (Integer) meth.invoke(null, new Integer(-1));编程
3.动态实例化类
Constructor是Java中提供类的单个构造方法的信息以及访问权限的封装类。
它容许在将实参与带有底层构造方法的形参的newInstance()匹配时进行扩辗转换,
可是若是发生收缩转换,则抛出IllegalArgumentExcetion。newInstance()方法能够
使用指定的参数来建立对象:
public T newInstance(Object...initargs)throws InstantiationException,IllegalAccessException,
IllegalArgumentException,InvocationTargetException
initargs: 将做为变量传递给构造方法调用的对象数组。数组
// 动态创建一个String对象,
Constructor<?> construtor = String.class
.getConstructor(String.class);
String str = (String) construtor.newInstance("000123");
4.动态代理
1.实现InvocationHandle 接口
InvocationHandle 接口是代理实例的调用处理程序实现的接口。每一个代理实例都具备一个关联的调用处理程序。
对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的invoke()方法:
2.实现invoke()方法方法。
3.实现方法,调用newProxyInstance方法。Proxy.newProxyInstance。
Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method method, Object[] args)。
在实际使用时,第一个参数obj通常是指代理类,method是被代理的方法,如上例中的trading(),
args为该方法的参数数组。这个抽象方法在代理类(代理处理类)中动态实现。
Proxy:该类即为动态代理类。
Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):
返回代理类的一个实例,返回后的代理类能够看成被代理类使用 (可以使用被代理类的在接口中声明过的方法)。
5.Class类的5种方式
java的数据类型能够分为两类,即引用类型和原始类型(即基本数据类型)。
1."Object.getClass()" : 若是一个类的对象可用,则最简单的得到Class的方法是使用Object.getClass()。
固然,此方式只对引用类型有效。
2. ".class"------------- : 若是类型可用但没有对象,则能够在类型后加上".class"来得到Class对象。这也是使原始类型
得到Class对象最简单的方式:
3."Class.forName()"---: 若是知道类的全名,则可使用静态方法Class.forName()来得到Class对象,它不能用在原始类型上,
可是能够用在原始类型数组上。(注:此方式会抛出ClassNotFoundException异常)
4. "包装类的TYPE域"-----: 每个原始类型和void都有包装类。利用其TYPE域就能够得到Class对象。编码
5."以Class为返回值的方法": 如获取内部类的getDeclaredClasses()方法,此时返回一个对象数组
class1 = Class.forName("java.lang.String");代理
6.查看类的定义
一般类的声明包括常见修饰符(public,protected,private,abstract,static,final,strictfp等)、
类的名称、类的泛型参数、类的继承类(实现的接口)、类的注解等信息。
Class类经常使用方法:
forName(String className)-: 根据给定的名称得到Class对象
getAnnotations()------------: 返回此Class对象上存在的注释
getCanonicalName() --------: 返回Java Language Specification 中所定义的底层类的规范化名称
getGenericInterfaces()------: 返回泛型形式的对象类所实现的接口
getGenericSuperclass() -----: 返回泛型形式的对象类所直接继承的超类
getModifuers() --------------: 返回此类或接口以整数编码的Java语言修饰符
getTypeParameters() -------: 按声明顺序返回TypeVariable对象的一个数组对象
注:Java语言预约义的注解只有@Deprecated能够在运行时得到。
7.得到Class对象表示实体的名称
注:
1.若是此类对象表示的是非数组类型的引用类型,则返回该类的二进制名称。
2.若是此类对象表示一个基本类型或者void,则返回其对应的Java语言的关键字的字符串。
3.若是此类对象表示一个数组类,名字的内部形式为"[元素编码",其深度为几维,就有几个"["。
其元素类型编码为:
——————————————————————————————————————————————————
元素类型 编 码
boolean Z
byte B
char C
short S
int I
float F
double D
long J
class or interfaces Lclassname(即当元素是引用类型或者接口的时候,编码为"L+类名") 排序
System.out.println("获取非数组类型的引用类型,返回该类的二进制名称: "
+ new String().getClass().getName());
8.类的成员
getConstructors() -------: 返回由该类对象的全部构造方法组成的数组
getDeclaredFields() -----: 返回由该类对象的全部非继承域组成的数组
getDeclaredMethods() -- : 返回由该类对象的全部非继承方法组成的数组
getFields() -------------- : 返回由该类对象的全部公共域组成的数组
getMethod() -------------: 返回由该类对象的全部公共方法组成的数组继承
Class<?> strclass = new String().getClass();接口
// 查看构造方法
System.out.println(strclass.getName() + "的构造方法有:");
Constructor<?>[] constructors = strclass.getConstructors();
if (constructors.length > 0) {
for (Constructor<?> constructor : constructors) {
System.out.println("\t" + constructor);
}
} else {
System.out.println("空");
}
9.内部类消息
Class类的getDeclaredClasses()方法返回Class对象的一个数组,这些对象反映声明为该Class对象
所表示的类的成员的全部类和接口,包括该类所声明的公共、保护、默认(包)访问及私有类和接口,
但不包括继承的类和接口。若该类不将任何类或接口声明为成员,或者该对象表示基本类型、数组类或
void,则该方法返回一个长度为0的数组。
public Class<?> [] getDeclaredClasses() throws SecurityExceptionci
Class<?> clazz = new String().getClass(); Class[] class1 = clazz.getDeclaredClasses(); for (int i = 0; i < class1.length; i++) { Class<?> innerclass = class1[i]; } 10.继承层次对类排序 Java提供了instanceof运算符来比较两个类(或接口)之间是否存在继承关系。 TreeSet<E> 是基于TreeMap的NavigableSet实现的。它使用元素的天然顺序对 元素进行排序,或者根据建立set时提供的Comparator进行排序,具体取决于 使用的构造方法。本节采用Class类中的isAssignableFrom()方法来判断当前 Class 对象所表示的类与给定的Class对象所表示的类之间的关系,若相同或 是父类则返回true,不然返回false。 public boolean isAssignableFrom(Class<?> clazz) 注:Java中与排序相关的接口有Comparable和Comparator。这两个接口经过对象之 间比较的结果--一个有符号的整数来比较对象的大小。实现任何一个接口均可 以让对象具备排序的能力。固能够用TreeSet也能够用Arrays.sort()来进行排序。 TreeSet<Class<?>> treeSet = new TreeSet<Class<?>>( new CompareClasses()); System.out.println("添加类——JComponent.class"); treeSet.add(JComponent.class); System.out .println("添加类——Container.class"); treeSet.add(Container.class);