class类
反射的功能
获取Class类
代码
// 方式一通过getClass
Class cc1=u1.getClass();
// 方式二通过包名
Class cc2=Class.forName("com.fu.bean.user");
// 方式三通过类命.class
Class cc3=user.class;
// 方式四基本内置类型都有一个type属性 可以返回class
Class cc4=String.class;
// 方式五 获得父类的class
Class cc4=c1.getSuperclass();
什么类型有class对象
Class c1=Object.class;//对象
Class c2= Serializable.class;//接口
Class c3=String[].class;//数组
Class c4=int[][].class;//二维数组
Class c5=Test.class;//注解
Class c6=int.class;//基本类型
Class c7=void.class;//void
Class c8=Class.class;//class
java内存分析
类的加载过程
类加载器
BootstrapClassLoader(启动类加载器)
c++
编写,加载java
核心库 java.*
,构造ExtClassLoader
和AppClassLoader
。由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作
ExtClassLoader (标准扩展类加载器)
java
编写,加载扩展库,如classpath
中的jre
,javax.*
或者java.ext.dir
指定位置中的类,开发者可以直接使用标准扩展类加载器。
AppClassLoader(系统类加载器)
java
编写,加载程序所在的目录,如user.dir
所在的位置的class
CustomClassLoader(用户自定义类加载器)
java
编写,用户自定义的类加载器,可加载指定路径的class
文件
源码分析
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
// 首先检查这个classsh是否已经加载过了
Class<?> c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
try {
// c==null表示没有加载,如果有父类的加载器则让父类加载器加载
if (parent != null) {
c = parent.loadClass(name, false);
} else {
//如果父类的加载器为空 则说明递归到bootStrapClassloader了
//bootStrapClassloader比较特殊无法通过get获取
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {}
if (c == null) {
//如果bootstrapClassLoader 仍然没有加载过,则递归回来,尝试自己去加载class
long t1 = System.nanoTime();
c = findClass(name);
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
双亲委派机制
通过反射获得构造器、方法、属性等
Class c1=Class.forName("com.fu.bean.user");
System.out.println(c1.getName());// get package name and class name
System.out.println(c1.getSimpleName()); // get class name
Field[] fields = c1.getFields();// only can find public attributes
for (Field field : fields) {
System.out.println(field);
}
fields=c1.getDeclaredFields();//can find all attributes
for (Field field : fields) {
System.out.println(field);
}
//Gets a public specified property
// Field name=c1.getField("name");
// System.out.println(name);
// Gets a specified property
Field name=c1.getDeclaredField("name");
System.out.println(name);
System.out.println("======================");
Method[] method = c1.getMethods();//找到本类和父类的全部的public的方法
for (Method method1 : method) {
System.out.println(method1);
}
System.out.println("======================");
Method[] declaredMethods = c1.getDeclaredMethods();//找到本类的全部方法
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
System.out.println("======================");
//获得指定方法
Method m1=c1.getMethod("getName");
System.out.println(m1);
Method m2=c1.getDeclaredMethod("setAge", int.class);
System.out.println(m2);
System.out.println("======================");
//获得全部构造器
Constructor[] con=c1.getConstructors();
for (Constructor constructor : con) {
System.out.println(constructor);
}
System.out.println("======================");
Constructor[] con2=c1.getDeclaredConstructors();
for (Constructor constructor : con2) {
System.out.println(constructor);
}
System.out.println("======================");
//获得指定构造器
Constructor conn=c1.getConstructor(String.class,int.class);
System.out.println(conn);
System.out.println("======================");
// invoke (调用)激活(参数1:对象名,参数2:值) 通过反射得到的方法调用
user uu1= (user) c1.newInstance();
Method setName = c1.getMethod("setName", String.class);
setName.invoke(uu1,"fdy");
System.out.println(uu1.getName());
System.out.println("======================");
// 不可能直接对private的field属性用set方法,需要使用setAccessible()破解权限
user uu2= (user) c1.newInstance();
Field age = c1.getDeclaredField("age");
age.setAccessible(true);
age.set(uu2,18);
System.out.println(uu2.getAge());
tips
如果需要频繁调用反射, 可以把 检测关闭了setAccessible(true)
获取泛型消息
public class test05 {
public void tese01(Map<String,Integer> map, List<Double> list){
System.out.println(233);
}
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
Class test05 = Class.forName("test05");
Method tese01 = test05.getMethod("tese01", Map.class, List.class);
Type[] genericParameterTypes = tese01.getGenericParameterTypes();
for (Type genericParameterType : genericParameterTypes) {
System.out.println(genericParameterType);
if(genericParameterType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
}
}