什么是RTTI
RTTI 既是 运行时,识别对象和类的信息;
两种形式:
一 : 传统的TRRI 假设在编译时已经知道了所有的类型信息(比如存入List数组中 全部转换为Object (向上转型),取出时 在有OBject 向下转型 取出我们的数据类型数据)
二 : 反射 机制 ,在运行时发现和使用类的信息
**Class 对象 : 类的信息**
class 对象包含了与类有关的信息,事实上 Java中是用Class对象来创建这个类中的所有的对象;每当编译完成,就会生成一个Class对象,被保存在.class文件中.JVM使用ClassLoader(类加载器)来加载对象,所有的类都是在对其第一次使用(静态成员被引用,静态常量除外) 或者new 关键字创建对象后,动态加载到JVM中.所谓的动态加载也就是在被使用到时才去加载.
Class对象来完成类型信息在运行上表示;
Class对象包含与类有关的消息,Class对象就是用来创建所有的"常规对象",
Java使用Class对象来执行RTTI,即使你正在执行类似类型转换这样的操作!
每个类都会产生一个对应的Class对象,也就是保存在.class文件中;所有类都是在对其第一次使用时,动态加载到JVM的,当程序创建一个对类的静态成员引用时,就会加载这个类,Class对象仅在需要的时候才会加载,static初始化是在类加载时进行的
编译期 传统的TRRI
编译器将检查类型向下转型是否合法,如果不合法就将抛出异常.向下转换类型前,可以使用instanceof判断
编译器在编译时打开和检查.class文件
List<String> list = new ArraysList<>();
list.add("字符串"); --- instanceof 判断类型是否一致 ---> 存入 (Object)String --> Object
System.out.println(list); ------> 取出 (String)Object --->String
反射 : 运行时类信息
运行时打开和检查.class文件
动态代理
代理模式是为了提供额外的 或者 不同的操作 而插入的用来替代 实际对想 的 对象
在动态代理中所有的掉用都会被重定向到单一的调节处理器上
接口和实现类:
public interface Interface { //接口
void doSomething();
void somethingElse(String arg);
}
public class RealObject implements Interface { //继承接口 实现类
public void doSomething() {
System.out.println("doSomething.");
}
public void somethingElse(String arg) {
System.out.println("somethingElse " + arg);
}
}
动态代理对象处理器:
public class DynamicProxyHandler implements InvocationHandler {
private Object proxyed;
public DynamicProxyHandler(Object proxyed) {
this.proxyed = proxyed;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
System.out.println("代理工作了.");
return method.invoke(proxyed, args);
}
}
测试类:
public class Main {
public static void main(String[] args) {
RealObject real = new RealObject();
Interface proxy = (Interface) Proxy.newProxyInstance(
Interface.class.getClassLoader(), new Class[] {Interface.class},
new DynamicProxyHandler(real));
proxy.doSomething();
proxy.somethingElse("luoxn28");
}
}
手写一个简单的
public interface MyInterface {
void eat();
void run(String str);
}
public class Dog implements MyInterface {
@Override
public void eat() {
System.out.println("吃骨头");
}
@Override
public void run(String str) {
System.out.println("我在跑---" + str);
}
}
public class test {
public static void main(String[] args) {
Dog dog = new dog(); //开始进行动态代理
MyInterface a = (MyInterface) Proxy.newProxyInstance(MyInterface.class.getClassLoader(),
new Class[]{MyInterface.class},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("动态代理执行了");
// System.out.println(proxy); //解开回报错
System.out.println(method.getName()); //方法信息
System.out.println(Arrays.toString(args)); //参数信息
return method.invoke(dog,args); //执行原方法
}
}
);
a.eat();
a.run("aaa");
}
}
//Lambda
MyInterface a = (MyInterface) Proxy.newProxyInstance(MyInterface.class.getClassLoader(),
new Class[]{MyInterface.class},
(Object proxy, Method method, Object[] argss )->{
System.out.println("动态代理执行了");
// System.out.println(proxy); //解开回报错
System.out.println(method.getName()); //方法信息
System.out.println(Arrays.toString(argss)); //参数信息
return method.invoke(dog,args); //执行原方法
}
);