反射
遇到的问题
尝试常规方法解决1(无果)
反射机制,它允许我们在运行时发现和使用类型的信息。
在java中用来表示运行时类型信息对应类就是Class类,Class类也是一个实实在在的类,存在于JDK的java.lang包中
利用反射机制解决
只修改配置文件而不用修改源码就可以实现

<re.properties> classfullpath=com.ljm.Reflection_.Cat method=hi

public class ReflectionQuestion { public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { //根据配置文件 re.properties 指定信息, 创建Cat对象并调用方法hi //老韩回忆 //传统的方式 new 对象 -》 调用方法 // Cat cat = new Cat(); // cat.hi(); ===> cat.cry() 修改源码. //我们尝试做一做 -> 明白反射 //1. 使用Properties 类, 可以读写配置文件 Properties properties = new Properties(); properties.load(new FileInputStream("src\\re.properties")); String classfullpath = properties.get("classfullpath").toString();//"com.hspedu.Cat" String methodName = properties.get("method").toString();//"hi" System.out.println("classfullpath=" + classfullpath); System.out.println("method=" + methodName); //2. 创建对象 , 传统的方法,行不通 =》 反射机制 //new classfullpath(); //3. 使用反射机制解决 //(1) 加载类, 返回Class类型的对象cls Class cls = Class.forName(classfullpath); //(2) 通过 cls 得到你加载的类 com.hspedu.Cat 的对象实例 Object o = cls.newInstance(); System.out.println("o的运行类型=" + o.getClass()); //运行类型 //(3) 通过 cls (对象)得到你加载的类 com.hspedu.Cat 的 methodName"hi" 的方法对象 // 即:在反射中,可以把方法视为对象(万物皆对象) Method method1 = cls.getMethod(methodName); //(4) 通过method1 调用方法: 即通过方法对象来实现调用方法 [与常规(对象.方法)的相反=>(方法.对象)] System.out.println("============================="); method1.invoke(o); //传统方法 对象.方法() , 反射机制 方法.invoke(对象) //反射机制是java框架的灵魂 } }
反射机制
根据对象反射出对象所在的类
把类的属性全部转成相关的对象了

//java.lang.reflect.Field: 代表类的成员变量, Field对象表示某个类的成员变量 //得到name字段 //getField不能得到私有的属性 Field nameField = cls.getField("age"); // System.out.println(nameField.get(o)); // 传统写法 对象.成员变量 , 反射 : 成员变量对象.get(对象) //java.lang.reflect.Constructor: 代表类的构造方法, Constructor对象表示构造器 Constructor constructor = cls.getConstructor(); //()中可以指定构造器参数类型, 返回无参构造器 System.out.println(constructor);//Cat() Constructor constructor2 = cls.getConstructor(String.class); //这里老师传入的 String.class 就是String类的Class对象 System.out.println(constructor2);//Cat(String name)
hi.setAccessible(true); //取消访问检查,提高速度
716 同一个类只加载一次(堆内存中) 不管是正常加载还是反射
Class常用方法:
获取对象 / 获取运行类型 /获取包名 /class对象创建对象 / 通过反射获取属性 /通过反射给属性赋值 /获得所有属性

public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException { String classAllPath = "com.lll.Reflection_.Car"; //1 . 获取到Car类 对应的 Class对象 //<?> 表示不确定的Java类型 Class<?> cls = Class.forName(classAllPath); //2. 输出cls System.out.println(cls); //显示cls对象, 是哪个类的Class对象 com.hspedu.Car System.out.println(cls.getClass());//输出cls运行类型 java.lang.Class //3. 得到包名 System.out.println(cls.getPackage().getName());//包名 //4. 得到全类名 System.out.println(cls.getName()); //5. 通过cls创建对象实例 Car car = (Car) cls.newInstance(); System.out.println(car);//car.toString() //6. 通过反射获取属性 brand Field brand = cls.getField("brand"); System.out.println(brand.get(car));//宝马 //7. 通过反射给属性赋值 brand.set(car, "奔驰"); System.out.println(brand.get(car));//奔驰 //8 我希望大家可以得到所有的属性(字段) System.out.println("=======所有的字段属性===="); Field[] fields = cls.getFields(); for (Field f : fields) { System.out.println(f.getName());//名称 } }
获得Class对象的6种方法

public static void main(String[] args) throws ClassNotFoundException { //1. Class.forName String classAllPath = "com.hspedu.Car"; //通过读取配置文件获取 Class<?> cls1 = Class.forName(classAllPath); System.out.println(cls1); //2. 类名.class , 应用场景: 用于参数传递 ,通过反射得到对应构造器对象 //类加载阶段 //Constructor constructor2 = cls.getConstructor(String.class); // 这里传入的 String.class 就是String类的Class对象 // System.out.println(constructor2);//Cat(String name) Class cls2 = Car.class; System.out.println(cls2); //3. 对象.getClass(), 应用场景,有对象实例 Car car = new Car(); Class cls3 = car.getClass(); System.out.println(cls3); //4. 通过类加载器【4种】来获取到类的Class对象 //(1)先得到类(car)加载器 的对象classLoader ClassLoader classLoader = car.getClass().getClassLoader(); //(2)通过类加载器得到Class对象 Class cls4 = classLoader.loadClass(classAllPath); System.out.println(cls4); //cls1 , cls2 , cls3 , cls4 其实是同一个对象 System.out.println(cls1.hashCode()); System.out.println(cls2.hashCode()); System.out.println(cls3.hashCode()); System.out.println(cls4.hashCode()); //5. 基本数据(int, char,boolean,float,double,byte,long,short) 按如下方式得到Class类对象 Class<Integer> integerClass = int.class; Class<Character> characterClass = char.class; Class<Boolean> booleanClass = boolean.class; System.out.println(integerClass);//int //6. 基本数据类型对应的包装类,可以通过 .TYPE 得到Class类对象 Class<Integer> type1 = Integer.TYPE; Class<Character> type2 = Character.TYPE; //其它包装类BOOLEAN, DOUBLE, LONG,BYTE等待 System.out.println(type1); System.out.println(integerClass.hashCode());//? System.out.println(type1.hashCode());//? }

public static void main(String[] args) { Class<String> cls1 = String.class;//外部类 Class<Serializable> cls2 = Serializable.class;//接口 Class<Integer[]> cls3 = Integer[].class;//数组 Class<float[][]> cls4 = float[][].class;//二维数组 Class<Deprecated> cls5 = Deprecated.class;//注解 //枚举 Class<Thread.State> cls6 = Thread.State.class; Class<Long> cls7 = long.class;//基本数据类型 Class<Void> cls8 = void.class;//void数据类型 Class<Class> cls9 = Class.class;// System.out.println(cls1); System.out.println(cls2); System.out.println(cls3); System.out.println(cls4); System.out.println(cls5); System.out.println(cls6); System.out.println(cls7); System.out.println(cls8); System.out.println(cls9); }
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术