------- android培训、java培训、期待与您交流!----------
instanceof关键字:
用于判断某个对象所属类型
格式:
对象 instanceof 类名 (返回值为布尔类型)
代码实现:
package cn.itcast; public class Demo { public static void main(String[] args) { Animal a = new Animal(); System.out.println(a instanceof Animal); System.out.println(a instanceof Cat); System.out.println("=========================================="); Cat c = new Cat(); System.out.println(c instanceof Animal); System.out.println(c instanceof Cat); System.out.println("=========================================="); Animal ac = new Cat(); System.out.println(ac instanceof Animal); System.out.println(ac instanceof Cat); } }
package cn.itcast; public class Animal { }
package cn.itcast; public class Cat extends Animal { }
类加载器
当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。
加载:
就是指将class文件读入内存,并为之创建一个Class对象。
任何类被使用时系统都会建立一个Class对象。
连接:
验证 是否有正确的内部结构,并和其他类协调一致
准备 负责为类的静态成员分配内存,并设置默认初始化值
解析 将类的二进制数据中的符号引用替换为直接引用
初始化:
就是我们以前讲过的初始化步骤
类的初始化时机:
创建类的实例
访问类的静态变量,或者为静态变量赋值
调用类的静态方法
使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
初始化某个类的子类
直接使用java.exe命令来运行某个主类
类加载器:
负责将.class文件加载到内存中,并为之生成对应的Class对象。
虽然我们不需要关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行。
组成:
Bootstrap ClassLoader 根类加载器
也被称为引导类加载器,负责Java核心类的加载
比如System,String等。在JDK中JRE的lib目录下rt.jar文件中
Extension ClassLoader 扩展类加载器
负责JRE的扩展目录中jar包的加载。
在JDK中JRE的lib目录下ext目录
System ClassLoader 系统类加载器
负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径
反射
概述:
反射机制:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
反射技术:要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
反射的好处:大大的增强了程序的扩展性
获取字节码对象:
方式一:
Person p = new Person();
Class c = p.getClass();
通过对象获取字节码文件对象
方式二:
Class c2 = Person.class;
任意数据类型都具备一个class静态属性,看上去要比第一种方式简单.
方式三:
Class c3 = Class.forName("全限定名");
将类名作为字符串传递给Class类中的静态方法forName即可。
public static Class forName(String className)throws ClassNotFoundException通过类名获取字节码文件对象
代码实现:
package cn.itcast; public class Demo2 { public static void main(String[] args) throws ClassNotFoundException { //通过对象获取字节码文件对象 Animal animal = new Animal(); Class clazz = animal.getClass(); //任意数据类型都具备一个class静态属性,看上去要比第一种方式简单 Class clazz2 = Animal.class; System.out.println(clazz2); //将类名作为字符串传递给Class类中的静态方法forName即可。 Class clazz3 = Class.forName("cn.itcast.Animal"); System.out.println(clazz3); } }
package cn.itcast; public class Animal { }
package cn.itcast; public class Cat extends Animal { }
构造方法反射的标准步骤:
public Constructor[] getConstructors()throws SecurityException获取该字节码文件对象的所有公共的构造方法
public Constructor[] getDeclaredConstructors()throws SecurityException获取该字节码文件对象的所有声明的构造方法
public Constructor<T> getConstructor(Class<?>... parameterTypes)throws NoSuchMethodException,SecurityException获取一个公共的构造
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)throws NoSuchMethodException,SecurityException获取一个声明的构造
代码实现:
package cn.itcast; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class Demo3 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Class clazz = Animal.class; Class clazz2 = new Animal().getClass(); Class clazz3 = Class.forName("cn.itcast.Animal"); // 获取Person的字节码文件对象 Class clazz4 = Person.class; // 调用Class的方法,获取Person类的构造方法 Constructor[] constructors = clazz4.getConstructors(); for (Constructor constructor : constructors) { //System.out.println(constructor); } System.out .println("===================================================="); Constructor[] declaredConstructors = clazz4.getDeclaredConstructors(); for (Constructor constructor : declaredConstructors) { //System.out.println(constructor); } // 使用方法获取一个空参构造 Constructor cfor0 = clazz4.getDeclaredConstructor(); // 使用方法获取一个带三个参数的构造 Constructor cfor3 = clazz4.getDeclaredConstructor(String.class, int.class, String.class); //跳过权限检查:暴力反射 cfor3.setAccessible(true); // 使用对应的构造方法对象 Object newInstance = cfor0.newInstance(); System.out.println((Person)newInstance); Object newInstance2 = cfor3.newInstance("唐嫣",18,"女"); Person p = (Person)newInstance2; System.out.println(p); System.out.println(p.age); } }
反射普通方法
public Method[] getMethods() throws SecurityException 获取所有公共的方法,包括继承的方法
public Method[] getDeclaredMethods() throws SecurityException 获取所有声明的方法
public Method getDeclaredMethod(String name,Class<?>... parameterTypes)throws NoSuchMethodException,SecurityException
name:方法名称 parameterTypes:参数的类型
public Object invoke(Object obj, Object... args)throws IllegalAccessException,IllegalArgumentException,InvocationTargetException 执行方法
obj:我要执行哪个对象的方法 args:方法的参数
代码实现:
package cn.itcast; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Demo5 { public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { // 获取字节码文件对象 Class clazz = Person.class; // 调用方法获取普通方法 // Method[] methods = clazz.getMethods(); // for (Method method : methods) { // System.out.println(method); // } // System.out.println("============================"); // Method[] methods2 = clazz.getDeclaredMethods(); // for (Method method : methods2) { // System.out.println(method); // } // 反射一个普通方法,空参,一个参数 Method mfor0 = clazz.getDeclaredMethod("method2"); Method mfor1 = clazz.getDeclaredMethod("method3", String.class); Method mforReturn = clazz.getDeclaredMethod("method"); //使用方法 Person p = new Person("唐嫣",18); Person p2 = new Person("诗诗",38); mfor0.invoke(p); //由于一个参数的方法是私有化方法,外界无法访问,所有需要暴力反射 mfor1.setAccessible(true); mfor1.invoke(p2, "我被调用了"); Object result = mforReturn.invoke(p); System.out.println(result); } }
动态代理
代理者 代理 被代理者 执行方法
执行方法:本来是被代理者的方法,却被代理者代理执行了
这里的动态:
代理的方法是动态的。
JDK提供的代理只能针对接口做代理。
Proxy:代理类
创建动态代理类对象
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h)throws IllegalArgumentException通过该方法返回代理对象
InvocationHandler: 接口
用于定义如何代理
Object invoke(Object proxy,Method method,Object[] args)throws Throwable这个方法定义了代理类如何代理
proxy:代表代理对象,但是这里不使用!
method: 要被代理的方法 就是那个动态的方法
args:参数
代码实现:
package cn.itcast2; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; public class Demo { public static void main(String[] args) { //被代理者 Person p = new Person(); //代理者:代理对象 ClassLoader loader = p.getClass().getClassLoader(); Class<?>[] interfaces = p.getClass().getInterfaces(); //创建InvocationHandler对象 InvocationHandler ih = new MyHandler(p); //代理对象 Object object = Proxy.newProxyInstance(loader, interfaces, ih); Animal myProxy = (Animal)object; //通过代理对象调用方法 myProxy.eat(); myProxy.sleep(3); String sport = myProxy.sport(); System.out.println(sport); } }
package cn.itcast2; public interface Animal { //吃饭的方法 void eat(); //睡觉的方法 void sleep(int times); //运动 String sport(); }
package cn.itcast2; public class Person implements Animal { @Override public void eat() { System.out.println("吃了"); } @Override public void sleep(int times) { System.out.println("一天睡"+times+"觉"); } @Override public String sport() { return "敲代码"; } }
package cn.itcast2; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /* * 定义InvocationHandler的子类对象 * */ public class MyHandler implements InvocationHandler { //定义成员变量,用来接收 被代理者 Person p; public MyHandler(Person p) { this.p = p; } //该方法定义具体如何代理 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //添加一些其他的更强大的功能 //验证这个动物是不是人,人才可以调用 //通过反射的方式调用方法 Object result = method.invoke(p, args); //添加一些其他的更强大的功能 //返回方法返回值 return result; } }