婚纱摄影网站图片,长春网站排名公司,云落主题WordPress,东风地区网站建设价格低目录 1.使用类对象
1.1创建对象
1.2使用对象属性
1.3使用方法
2.反射操作数组
3.反射获得泛型
4.类加载器
4.1双亲委派机制
4.2自定义加载器 1.使用类对象 通过反射使用类对象#xff0c;主要体现3个部分 创建对象#xff0c;调用方法#xff0c;调用属性#xff…目录 1.使用类对象
1.1创建对象
1.2使用对象属性
1.3使用方法
2.反射操作数组
3.反射获得泛型
4.类加载器
4.1双亲委派机制
4.2自定义加载器 1.使用类对象 通过反射使用类对象主要体现3个部分 创建对象调用方法调用属性存值取值
1.1创建对象
利用反射创建对象有两种方式 通过构造器创建对象推荐 通过Class直接创建对象只支持利用无参构造器创建对象
Object o c.newInstance(); //使用无参构造器创建对象Constructor con c.getConstructor(int.class, int.class);
//A a new A(10,20);
Object o con.newInstance(10, 20);
1.2使用对象属性 包括使用属性赋值 使用属性取值。 需要先获得要操作的属性对象
Object a1 c.newInstance();Field n c.getField(n); //获得的public的属性n.set(a1,XXXX);Object value n.get(a1);
System.out.println(value);
//私有属性可以通过设置i.setAccessible(true) 实现对私有成员的访问
//注意1 使用后建议将其重新锁住 i.setAccessible(false)
//注意2 强烈不推荐使用该方式操作私有成员建议通过封装提供对应的get和set方法。
Field i c.getDeclaredField(i);
i.setAccessible(true);
i.set(null,100); //传递null是因为i属性是一个static属性
Object value i.get(null);
System.out.println(value);
i.setAccessible(false); 在jdk1.9之后对java中的类库做了重新的处理 增加了一个模块的功能成员属于类类属于包包属于模块 模块属于程序 包中的类需要export导出其他模块中的类才可见。 包中未导出的类其他模块中的类不可见不可引入不可反射操作 当然可以通过jvm参数配置使得模块中的内容都可以反射操作。
1.3使用方法
反射调用对象的方法需要先获得对应的Method方法对象 获得Method对象时除了指定方法名还需要指定方法的参数列表Class 调用方法时需要指定所属对象static方法所属null或Class需要传递具体的参数值Object
Object a c.newInstance();
Method m c.getMethod(t1, int.class, int.class);//t1(int,int)
//a.t1(100,200);
Object r m.invoke(a, 100, 200);
Method m c.getDeclaredMethod(t2);//t2()
m.setAccessible(true);
m.invoke(a) ;
m.setAccessible(false);
2.反射操作数组
反射操作数组使用的是Array类
//Object array new int[5];
//array[1] (取值 赋值)
Object array Array.newInstance(int.class, 5);Array.set( array , 0 , 250 );Object value Array.get(array, 0);
System.out.println(value);int len Array.getLength(array);
System.out.println(len);
3.反射获得泛型
关于反射获得泛型有两种操作需求 获得类定义时的泛型 T , V , K , E
public static void t1(){Class c A.class;TypeVariable[] typeParameters c.getTypeParameters();//类定义时的泛型System.out.println(typeParameters.length);System.out.println(typeParameters[0].getName());
} 2.获得类使用时的泛型具体的类型 ListString
public static void t2() throws NoSuchFieldException, NoSuchMethodException {Class c B.class ;Field a c.getDeclaredField(a);Type type a.getGenericType();//一般getGeneric系列都是用来获得所包含的泛型的。//属性类型返回类型参数类型父类型父接口类型都有该系列方法//Class is a Type //泛型类型也称为参数化类型 is a Type , 本质是 ParameterizedTypeParameterizedType pt (ParameterizedType) type;//Type[] pts pt.getActualTypeArguments(); //获得多个泛型的数组Type rawType pt.getRawType();//获得泛型类型}
4.类加载器 JVM在运行程序时会使用类加载器加载读取类文件的信息并对其进行一系列的处理最终将其存储在方法区并生成与之对应的Class对象。 类信息有不同的情况 有我们自己的写的类信息 有jdk自带的类信息 未来可能还有其他的类信息如网络中的类信息需要加密处理类信息等。 jdk针对于不同的类信息情况提供了不同的类加载器默认有3种 BootstrapClassLoader 启动类加载器使用C/C实现加载jdk基本类库如java.lang等 ExtClassLoader 扩展类加载器使用Java实现的加载jdk扩展类库 AppClassLoader 应用类加载器使用Java实现的classpath路径中的类我们自己编写的类
4.1双亲委派机制 jdk提供了3个加载器未来我们还能自定义加载器 jdk同时提供了双亲委派机制使得多个加载器可以更合理的协作应用 当我们在程序中需要使用一个类时会先向最底层的类加载器申请这个类app 如果app加载器加载过这个类就会返回该类的Class对象 如果app没有加载过这个类app会向其父级加载器ext申请这个类 如果ext加载过就返回这个类如果没有加载过这个类继续想起父级Bootstrap申请 如果bootstrap加载过就返回这个类如果没有加载过就尝试加载 如果在bootstrap的加载范围内则加载这个类 如果不再bootstrap的加载范围内 尝试让ext加载 如果在ext加载范围内就让ext加载。如果不在就尝试让app加载 如果在app加载范围内就让app加载否则就抛出ClassNotFoundException 注意app 和 ext 和 bootstrap是逻辑上的子父级关系不是真正 的extends继承关系 双亲委派机制的优点 防止核心类被篡改。 方式类重复加载 防止在核心包中扩展类沙箱机制
4.2自定义加载器 哪些情况需要自定义类加载器呢 扩展加载源 如从网络中加载类库 类的隔离 类信息的解密 如何自定义类加载器 自定义加载器类 继承ClassLoader 重写方法 可以重写loadClass方法但不推荐。因为该方法中提供了双亲委派机制 如果重写该方法相等于破坏了双亲委派机制。 可以重写findClass方法根据需求去指定的地方获取类文件信息 以byte[]的形式装载找到的类信息 还有一个很重要的方法defineClass(),用来将字节码内容进行一系列的处理并存储在方法区并生成Class对象 所以在findClass之后一定要调用该方法。 使用类加载器
public class MyClassLoader extends ClassLoader{//name 一般就是com.buka.User 类路径//可以根据这个类路径确定最重要加载的目标类Overrideprotected Class? findClass(String name) throws ClassNotFoundException {try {Socket link new Socket(localhost,6666);InputStream is link.getInputStream();//存储所有读取到的字节信息//本来是需要使用字节数组//但无法确定从网络中读取字节的数量就不知道要定义多长的字节数组//可以使用ByteArrayOutputStreamByteArrayOutputStream bos new ByteArrayOutputStream();byte[] bs new byte[010];while(true){int len is.read(bs);if(len -1){break ;}bos.write(bs,0,len);}byte[] content bos.toByteArray();return super.defineClass(X,content,0,content.length);} catch (IOException e) {throw new RuntimeException(e);}}
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {MyClassLoader loader new MyClassLoader();Class? c loader.loadClass(X);c.newInstance();
}