获取类的Class对象的方法
//使用new获取对象来获取类对象
Demo2 demo2 = new Demo2("小王");
Class<? extends Demo2> aClass = demo2.getClass();
System.out.println(aClass.toString());
//使用类名.class 属性
Class<?>class1 =Demo2.class;
System.out.println(class1.toString());
//通过Class.forname()方法获得该类的Class对象
Class<?> aClass1 = Class.forName("theday59.Demo2");
System.out.println(aClass1.toString());
输出结果
class theday59.Demo2
class theday59.Demo2
class theday59.Demo2
对于Class文件的常用方法
-
获取类的全名称
-
Class<?> aClass = Class.forName("theday59.Demo2"); String name = aClass.getName(); System.out.println(name);
-
theday59.Demo2
-
-
获取类的父类名称
-
Class<?> aClass = Class.forName("theday59.Demo2"); System.out.println(aClass.getSuperclass().getName());
-
java.lang.Object
-
-
获取接口信息
-
Class<?> aClass = Class.forName("theday59.Demo2"); Class<?>[] interfaces = aClass.getInterfaces(); System.out.println(Arrays.toString(interfaces));
-
输出的是一个数组信息
-
-
获取类的所有构造方法 获取String类的所有构造方法
-
Class<?> aClass1 = Class.forName("java.lang.String"); Constructor<?>[] constructors = aClass1.getConstructors(); for (Constructor c:constructors){ System.out.println(c.toString()); }
-
-
获取无参构造
-
//第一种方法 Class<?> aClass1 = Class.forName("theday59.Demo2"); Constructor<?> constructor = aClass1.getConstructor(); Object o = constructor.newInstance(); System.out.println(o.toString()); //第二种方法:使用类对象.newInstance() Object o1 = aClass1.newInstance(); String s = o1.toString(); System.out.println(o1);
-
-
获取带参构造方法
-
Constructor<?> constructor = aClass.getConstructor(String.class,int.class); Object o = constructor.newInstance("小王",20); System.out.println(o.toString());
-
Demo2{name=‘小王’, age=20}
-
-
获取类中的方法,并调用方法
-
获取所有的public修饰的方法 包括从父类继承的方法
-
Method[] methods = aClass.getMethods();
-
-
获取所有的方法 包括public之外修饰方法名 (只能获得当前类的方法无法获得父类继承来的方法)
-
Method[] methods = aClass.getDeclaredMethods();
-
-
-
获取单个方法
-
//获取Demo2的Class对象 Class<?> aClass = Class.forName("theday59.Demo2"); //获取名为eat参数类型为String的方法 Method eat = aClass.getMethod("eat",String.class); //加载一个Demo2的类的对象demo2 Demo2 demo2= (Demo2)aClass.newInstance(); //传入demo2和参数信息 如果有返回值还需要再加入一个Object类型的变量 如果调用的是静态方法demo2改为null eat.invoke(demo2,"小李");
-
相当于new一个方法然后调用这个方法
-
-
获取私有方法,并调用方法
-
Demo2 demo2= (Demo2)aClass.newInstance(); Method flash = aClass.getDeclaredMethod("flash", String.class); //暴力反射 flash.setAccessible(true); flash.invoke(demo2,"xian");
-
-
可以调用任何方法的通用方法
-
public static Object invokeAny(Object obj, String methodName, Class<?>[] types, Object... args) throws Exception { //获取类对象 Class<?> class1 =obj.getClass(); //通过方法名和参数获取方法 Method method = class1.getDeclaredMethod(methodName,types); //当方法为private修饰时需要进行暴力反射 method.setAccessible(true); //返回反射的Object类对象 return method.invoke(obj,args); }
-
-
应用
-
//有一个Demo2类 其内有一个 private修饰的wash方法 参数为String类型 public class Demo2 { private void wash(String name){ System.out.println("private"+name+"吃完饭刷筷子"); } }
//新建一个Demo2对象 Demo2 demo2 = new Demo2(); //依次导入Demo2对象、方法名称、方法参数类型注意是一个数组类型需要new一个Class的数组,然后根据Class数组内的参数类型依次填入所要添加的的数据 invokeAny(demo2,"wash",new Class[]{String.class},"小王");
- 输出:private小王吃完饭刷筷子
-
-
获取类中的属性
-
//获取字段信息 返回的是一个字段数组 该方法只能获得public修饰的字段 Field[] fields = aClass.getFields(); //获取当前Class对象的所有字段信息 包括私有、默认、保护 Field[] fields = aClass.getDeclaredFields(); //获取单个属性 获取名为name的字段信息 Field name = aClass.getDeclaredField("name"); //设置字段信息和获取字段信息 Field name = aClass.getDeclaredField("name"); Demo2 demo2 = (Demo2) aClass.newInstance(); name.setAccessible(true); name.set(demo2,"xian"); name.get(demo2);
-
设计模式
工厂设计模式
- 工厂模式主要负责对象创建的问题
- 开闭原则,对拓展开放,对修改关闭 可以对工厂模式拓展新的对象,不允许修改工厂中的代码
- 可以通过反射进行工厂模式的设计,完成动态的对象创建
恶汉式单例
-
public class Person { //1.首先创建一个常量 private static final Person person = new Person(); //2.私有化构造方法,类外部无法创建对象 private Person(){} //3.通过一个公有的静态方法返回这个对象 public static Person getInstance(){ return person; } }
-
优点
- 线程安全
-
缺点
- 生命周期太长,浪费空间
懒汉式
-
public class Student { //1.首先创建一个对象,设为null private static Student student=null; //2.私有化构造方法 private Student(){} //3.通过公开方法返回对象 public static Student getInstance(){ if (student==null){ student=new Student();} return student; } }
-
优点:只有在调用getInstance方法时才会实例化 生命周期短 节省空间
-
缺点:线程不安全 需要同步
-
基于线程安全的加锁方法
-
public class Student { private static volatile Student student = null; private Student() { } public static Student getInstance() { // if (student == null) { synchronized (Student.class) { if (student == null) { student = new Student(); } } } return student; } }
-
懒汉式静态内部类写法
-
该方法既有生命周期短,节省空间的优点也有饿汉式的线程安全的优点
-
public class Teacher { //构建私有的构造方法 private Teacher() { } //构造静态的内部类方法 private static class Holder { private static Teacher teacher = new Teacher(); } //返回并调用静态的内部类 public static Teacher getInstance() { return Holder.teacher; } }