当前位置: 首页 > wzjs >正文

网站后台 灰色wordpress商城加导购

网站后台 灰色,wordpress商城加导购,wordpress优化搜索引擎,wordpress 上传ssl证书文章目录 引入类加载过程1. 通过 new 创建对象2. 通过反射创建对象2.1 触发加载但不初始化2.2 按需触发初始化2.3 选择性初始化控制 核心用法示例1. 通过无参构造函数创建实例对象2. 通过有参构造函数创建实例对象3. 反射通过私有构造函数创建对象, 破坏单例模式4. …

文章目录

  • 引入
    • 类加载过程
    • 1. 通过 new 创建对象
    • 2. 通过反射创建对象
      • 2.1 触发加载但不初始化
      • 2.2 按需触发初始化
      • 2.3 选择性初始化控制
  • 核心用法
  • 示例
    • 1. 通过无参构造函数创建实例对象
    • 2. 通过有参构造函数创建实例对象
    • 3. 反射通过私有构造函数创建对象, 破坏单例模式
    • 4. 通过反射获得类的public属性值, 演示getField与getDeclaredField两者的区别

引入

当我们刚接触java语言的时候, 我们最常写的代码应该就是初始化某个对象, 然后调用该 对象的方法。 如:

MyClass obj = new MyClass();
obj.doSth();

上面的这种用法的前提是, 我们在写代码的时候已经确定要去创建MyClass类的具体实例对象。
那如果我们想在代码运行的时候才去指定具体对象的类(比如根据传入的参数名称确定创建的类名),普通的硬编码方式将无法实现需求 ;反射登场了。
反射为什么可以实现呢, 这个就要先介绍一下类加载的过程了。

类加载过程

  1. 加载(Loading)
    JVM将类的字节码文件(.class)加载到内存,创建Class对象。
  2. 链接(Linking)
  • 验证:确保字节码符合规范。
  • 准备:为静态变量分配内存并赋予默认值(如int初始化为0)。
  • 解析:将符号引用转换为直接引用。
  1. 初始化(Initialization)
    执行类的静态代码块(static {})和静态变量显式赋值。

1. 通过 new 创建对象

new关键字会直接触发类的完整加载、链接和初始化过程:

  1. 若类未加载:
    - 立即执行加载、链接,完成后强制触发类的初始化(执行static代码块和初始化静态变量)。
  2. 初始化完成后:调用构造函数创建对象。
    示例:
// 第一次使用类时触发初始化
MyClass obj = new MyClass();

特点:

  • 类必须在编译时已知(硬编码依赖)。
  • 初始化在对象创建时必定发生。

2. 通过反射创建对象

通过反射(Class.newInstance()或Constructor.newInstance())创建对象时,允许分阶段控制类的加载过程:

2.1 触发加载但不初始化

使用ClassLoader.loadClass()可加载类但不初始化:

ClassLoader loader = MyClass.class.getClassLoader();
Class<?> clazz = loader.loadClass("MyClass"); // 仅加载和链接,不初始化

此时尚未执行静态代码块或静态变量显式赋值。

2.2 按需触发初始化

在首次需要初始化时才触发(如反射调用newInstance()):

Object obj = clazz.newInstance(); // 触发初始化 → 执行static代码块

2.3 选择性初始化控制

通过Class.forName可指定是否初始化:

public class Main {public static void main(String[] args) throws Exception {// 反射示例:ClassLoader loader = MyClass.class.getClassLoader();// 加载类但不初始化(第三个参数为类加载器)System.out.println("加载类但不初始化1...");Class<?> clazz2 = Class.forName("com.test.galaxy.MyClass", false, loader);// 加载类但不初始化System.out.println("加载类但不初始化2...");Class<?> clazz = loader.loadClass("com.test.galaxy.MyClass"); // 无输出// 触发初始化前,类的静态代码块仍未执行System.out.println("准备创建对象...");Object obj = clazz.newInstance(); // 输出:静态代码块执行!// 加载类同时触发初始化System.out.println("加载类同时触发初始化...");Class<?> clazz1 = Class.forName("com.test.galaxy.MyClass2");}
}
class MyClass {static {System.out.println("静态代码块执行!"); // 初始化触发}
}
class MyClass2 {static {System.out.println("静态代码块2执行!"); // 初始化触发}
}

特点:

  • 类的加载步骤可拆分(加载、链接、初始化分开触发)。
  • 初始化在需要时才发生(如通过newInstance())。
  • 灵活支持运行时动态加载类(例如插件化架构)。

核心用法

反射允许程序在运行时动态获取类的信息并操作类或对象。核心类是 Class,关键操作包括:

  • 动态创建对象(newInstance())
  • 调用方法(method.invoke())
  • 访问/修改字段(field.get()/set())

示例

1. 通过无参构造函数创建实例对象

import java.lang.reflect.Constructor;
public class ReflectionExample1 {public static void main(String[] args) {try {// 1. 获取Class对象(触发类加载,可能初始化)Class<?> clazz = Class.forName("com.test.galaxy.User");// 2. 获取无参构造方法(需处理异常)Constructor<?> constructor = clazz.getDeclaredConstructor();// 3. 调用newInstance()创建实例(无参数)Object instance = constructor.newInstance();System.out.println("实例创建成功:" + instance.getClass());} catch (Exception e) {e.printStackTrace();}}
}
class User {public User() {System.out.println("无参构造函数被调用!");}
}

关键说明

  • Class.forName():动态加载类,默认触发初始化。
  • getDeclaredConstructor():传入空参数类型列表表示获取无参构造方法。
  • 私有构造方法处理:若构造函数是私有(private),需调用 constructor.setAccessible(true) 解除访问限制。

2. 通过有参构造函数创建实例对象

import java.lang.reflect.Constructor;public class ReflectionExample2 {public static void main(String[] args) {try {// 1. 获取Class对象(注意使用全限定类名)Class<?> clazz = Class.forName("com.test.galaxy.User2");// 2. 指定参数类型列表,获取有参构造方法Class<?>[] paramTypes = {String.class, int.class}; // 参数类型顺序严格匹配Constructor<?> constructor = clazz.getDeclaredConstructor(paramTypes);// 3. 传递参数值实例化对象Object[] initArgs = {"张三", 25}; // 参数值顺序与类型列表一致Object instance = constructor.newInstance(initArgs);System.out.println("实例创建成功:" + instance.getClass());} catch (Exception e) {e.printStackTrace();}}
}
class User2 {private String name;private int age;public User2(String name, int age) {this.name = name;this.age = age;System.out.println("有参构造函数被调用!name=" + name + ", age=" + age);}
}

关键说明

  • 参数类型匹配:必须精确指定参数类型(如 int.class 不能写作 Integer.class)。
  • 参数值顺序:传入的参数值顺序需与声明时一致。
  • 可变长参数处理:若构造方法参数为可变长度(如 String…),类型写为 String[].class。

3. 反射通过私有构造函数创建对象, 破坏单例模式

import java.lang.reflect.Constructor;class Singleton {private static Singleton instance;private Singleton() {// 私有构造函数}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}
public class ReflectionExample3 {public static void main(String[] args) {try {// 通过正常方式获取单例对象Singleton instance1 = Singleton.getInstance();System.out.println("正常实例:" + instance1);// 方式 1:通过反射创建新实例(直接访问构造函数)Class<Singleton> clazz = Singleton.class;Constructor<Singleton> constructor = clazz.getDeclaredConstructor();constructor.setAccessible(true); // 访问私有构造函数Singleton instance2 = constructor.newInstance();// 方式 2:通过反射多次创建实例(动态控制)for (int i = 0; i < 3; i++) {Constructor<Singleton> ctor = clazz.getDeclaredConstructor();ctor.setAccessible(true);Singleton instance = ctor.newInstance();System.out.println("反射实例 " + (i+1) + ": " + instance);}// 验证两个实例是否相同System.out.println("instance1 == instance2 ? " + (instance1 == instance2));} catch (Exception e) {e.printStackTrace();}}
}

4. 通过反射获得类的public属性值, 演示getField与getDeclaredField两者的区别

  1. getField() 的特点
    • 只能获取 当前类及继承链中声明为 public 的属性;
    • 无法获取非 public 属性;
    • 可以直接访问继承的父类 public 属性。
  2. getDeclaredField() 的特点
    • 能获取 当前类中声明的所有属性(包括 private/protected/public);
    • 无法获取父类声明的属性;
    • 访问非 public 属性需通过 setAccessible(true)。
import java.lang.reflect.Field;class Parent {public String parentPublicField = "Parent-Public";private String parentPrivateField = "Parent-Private";
}
class Child extends Parent {public String childPublicField = "Child-Public";private String childPrivateField = "Child-Private";
}
public class ReflectionExample4 {public static void main(String[] args) {Child child = new Child();Class<?> clazz = Child.class;try {// ======================= 使用 getField() ========================// 1. 获取子类的 public 属性(成功)Field childPublicField = clazz.getField("childPublicField");System.out.println("[getField] 子类 public 属性: " + childPublicField.get(child));// 2. 获取父类的 public 属性(成功)Field parentPublicField = clazz.getField("parentPublicField");System.out.println("[getField] 父类 public 属性: " + parentPublicField.get(child));// 3. 尝试获取子类的 private 属性(失败,触发异常)clazz.getField("childPrivateField");} catch (Exception e) {System.err.println("[getField 失败] " + e.getClass().getSimpleName() + ": " + e.getMessage());}try {// ================== 使用 getDeclaredField() ======================// 1. 获取子类的 public 属性(成功)Field childPublicDeclaredField = clazz.getDeclaredField("childPublicField");System.out.println("[getDeclaredField] 子类 public 属性: " + childPublicDeclaredField.get(child));// 2. 获取子类的 private 属性(需解除访问限制)Field childPrivateDeclaredField = clazz.getDeclaredField("childPrivateField");childPrivateDeclaredField.setAccessible(true);  // 强制访问私有属性System.out.println("[getDeclaredField] 子类 private 属性: " + childPrivateDeclaredField.get(child));// 3. 尝试获取父类的属性(失败,无论是否是 public)clazz.getDeclaredField("parentPublicField");} catch (Exception e) {System.err.println("[getDeclaredField 失败] " + e.getClass().getSimpleName() + ": " + e.getMessage());}}
}
http://www.dtcms.com/wzjs/541301.html

相关文章:

  • 学摄影的网站有哪些佛山做网络优化的公司
  • 做网站认证对网站有什么好处便利的合肥网站建设
  • 吉安市建设技术培训中心网站建设部网站水利设计资质
  • 好的网站建设公司了解网站开发 后台流程
  • 删除织梦综合网站百度企业网站建设
  • 2023网站分享注册营业执照网上申请入口
  • 怎么区分营销型网站美容手机网站模板
  • 网站建设报价单及项目收费明细表百度一下官方网
  • 安徽网站建设公司wordpress怎么把设置菜单去除
  • 潍坊企业免费建站广州网站排名优化服务
  • 绍兴网站seo浙江省外贸公司排名
  • 定制网站大概多少钱网站需求分析报告
  • 如今做哪些网站能致富柚段子wordpress
  • 网站ico添加创意创新设计方案
  • ueeshop建站费用销售推广的方法都有哪些
  • 南昌城市旅游网站建设53货源网下载app
  • 聊城市城乡建设部网站查询成都网站建设成功案例单招网
  • 站群系统有哪些php mysql网站开发全程实例.pdf
  • 二级学院网站建设方案专门做家居的网站
  • 如何做 试题类 网站沈阳网站建设技术公司排名
  • 重庆电子商务网站seo获取网站浏览者手机号
  • 宝安区住房和建设局网站双减之下托管班合法吗
  • 做网站前台需要学什么 后台乐清门户网
  • 武鸣网站建设中德生态园网站定制
  • 帝国cms如何做网站设计师个人网站
  • wordpress做网站教程汽车网站建设参考文献开题报告
  • 运维 网站开发app软件推广策略有哪些
  • 品牌网站制作公司网站定制开发微信运营
  • 湘潭做网站 i磐石网络软件工程师工资
  • 河源市住房城乡和建设局网站咸宁 网站建设