运行程序:
编译:将.java文件编译生成对应的.class文件(字节码文件)
运行:基于字节码文件调用操作系统的资源执行程序
类加载:
面向对象:
万物皆对象
类 — 属性:特征 方法:行为
定义类:class 类名
Class类
当前类的字节码文件的对象类 — 表示类的类
类中包含的内容:
在方法的参数列表中,可以通过定义可变参数从而实现方法的参数个数由调用者确定;
格式:数据类型 … 名称
注意 :
方法参数列表中只能定义一个可变参数
方法参数列表中可以同时定义单个参数和可变参数,但是可变参数必须放到参数列表的最后
public class ChangeDemo { public static void main(String[] args) { System.out.println(add(3,5)); int[] arr = new int[]{3,1,5,7,6}; System.out.println(add(arr)); } public static int add(int ... arr){ // 以数组的形式传入 int sum = 0; for (int i : arr){ sum += i; } return sum; } }
优点:
简化了代码,提高了代码的复用性;
提高了代码的灵活性;
无需通过new就能创建当前正在运行的类或者接口实现类的对象
获取类的Class
类. class — > 返回Class类型的对象
Class clz = String.class; System.out.println(clz); // class java.lang.String Class clz1 = int.class; System.out.println(clz1); // int
类名.class调用类的class属性可以获取到该类的Class对象
对象.getClass()方法获取该对象对应的类的Class对象
String ss = new String(); System.out.println(ss.getClass()); // class java.lang.String
前提是有当前类的对象
根据类名获取该类对应的Class对象
Class.forName(全路径的类名)
;
Class clz = Class.forName("java.lang.String"); System.out.println(clz); // class java.lang.String
static Class<?> forName(String className)
: 返回与带有给定字符串名的类或接口相关联的 Class 对象。T newInstance()
: 创建此 Class 对象所表示的类的一个新实例。 注意:该方法仅仅适用于通过无参构造来创建对象;如果类中没有无参构造,则通过该方法创建对象会运行抛出异常 (这种方法已经过时)Constructor<T> getConstructor(Class<?>... parameterTypes)
:返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。Constructor<?>[] getConstructors()
:返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
:返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。Constructor<?>[] getDeclaredConstructors():返回 Constructor
对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。Field getField(String name)
: 返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共字段。Field[] getFields()
: 返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。Field getDeclaredField(String name)
: 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。Field[] getDeclaredFields()
: 返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。Method getMethod(String name, Class<?>... parameterTypes)
: 第一个参数表示方法名称, 第二个参数表示当前方法的参数列表的类型的Class对象,返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。Method[] getMethods()
:返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。Method getDeclaredMethod(String name, Class<?>... parameterTypes)
: 返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。Method[] getDeclaredMethods()
:返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。Constructor类:
T newInstance(Object... initargs)
: 使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。setAccessible(boolean flag)
: 将flag设置为true,可以进行暴力破解,不受权限控制Class<?>[] getExceptionTypes()
: 返回一组表示声明要抛出的异常类型的 Class 对象,这些异常是由此 Constructor 对象表示的底层构造方法抛出的。Class<?>[] getParameterTypes()
: 按照声明顺序返回一组 Class 对象,这些对象表示此 Constructor 对象所表示构造方法的形参类型。Field类:
Object get(Object obj)
:返回指定对象上此 Field 表示的字段的值。void set(Object obj, Object value)
:将指定对象变量上此 Field 对象表示的字段设置为指定的新值。Class<?> getType()
:返回一个 Class 对象,它标识了此 Field 对象所表示字段的声明类型。Method 类:
Object invoke(Object obj, Object... args)
:第一个参数指定调用哪个对象身上的方法,第二个参数:实参的值;对带有指定参数的指定对象调用由此 Method 对象表示的底层方法Class<?> getReturnType()
:返回一个 Class 对象,该对象描述了此 Method 对象所表示的方法的正式返回类型优点:
缺点:
可以绕过泛型的检查,可能会导致集合的使用出问题
打破了面向对象封装
示例:模拟数据库操作
public class DataBaseDemo { public static void main(String[] args) throws Exception { // 加载配置文件 Properties properties = new Properties(); properties.load(new FileInputStream(".\\dataBase.properties")); String value = properties.getProperty("DBName"); System.out.println(value); // 使用类名(value)创建对象 Class clz = Class.forName(value); System.out.println(clz); // class cn.ysu.reflect.MySql // newInstance() 获取Class对象对应的类的实例 (过时) // 只能用于无参构造 // Object o = clz.newInstance(); // 通过有参构造创建对象 Constructor constructor = clz.getConstructor(String.class); // 通过构造方法的 newInstance() 获取对象 Object o = constructor.newInstance("root"); // 获取私有构造方法 Constructor constructor1 = clz.getDeclaredConstructor(String.class, String.class); System.out.println(constructor1); // 私有 private cn.ysu.reflect.MySql(java.lang.String,java.lang.String) // 暴力破解 constructor1.setAccessible(true); // 获取对象 Object o1 = constructor1.newInstance("root", "123"); System.out.println(o1); // cn.ysu.reflect.MySql@723279cf DataBase db = (DataBase) o; db.insert(); // 获取抛出异常的构造方法 Class<?>[] getExceptionTypes() // Constructor constructor = clz.getConstructor(String.class); // Class[] exces = constructor.getExceptionTypes(); // for (Class c : exces){ // System.out.println(c); // class java.lang.Exception // } // 获取public修饰的属性 Field field = clz.getField("id"); System.out.println(field); // public java.lang.String cn.ysu.reflect.DataBase.id // Object get(Object obj): 获取当前属性的值 Object val = field.get(o); System.out.println(val); // root // 设置属性值 void set(Object obj, Object value) field.set(o,"zss"); System.out.println(field.get(o)); // zss Field field2 = clz.getDeclaredField("sql"); // 暴力破解 field2.setAccessible(true); field2.set(o1,"SELECT * FROM student"); Object psw = field2.get(o1); System.out.println(psw); // SELECT * FROM student // 获取方法 Method method = clz.getMethod("insert"); // 调用方法,需要指定调用的对象和参数值 method.invoke(o); // 获取私有方法 Method method1 = clz.getDeclaredMethod("delete"); // 调用方法 method1.setAccessible(true); // 获取方法返回值类型的对象 Class c = method1.getReturnType(); System.out.println(c); // boolean Object oo = method1.invoke(o); System.out.println(oo); // true } } abstract class DataBase{ public String id; public String psw; public abstract void insert(); } class MySql extends DataBase{ private String sql; public MySql(String id) throws Exception { if (id == null){ throw new Exception(); } this.id = id; System.out.println("通过有参构造创建对象,一个参数"); } private MySql(String id, String psw){ this.psw = psw; this.id = id; System.out.println("通过有参构造创建对象,两个参数"); } public void insert(){ System.out.println("从Mysql数据库中插入数据"); } private boolean delete(){ System.out.println("从Mysql数据库中删除数据"); return true; } } class Oracle extends DataBase{ public void insert(){ System.out.println("从Oracle数据库中插入数据"); } }
dataBase.properties文件内容
DBName = cn.sss.reflect.MySql