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

站长之家官网网址说说seo论坛

站长之家官网网址,说说seo论坛,做网站找哪家好 07月,做网站写页面多少钱的反射(Reflection)是一种强大的机制,允许程序在运行时动态获取类的信息、操作类的成员(属性、方法、构造器),甚至修改类的行为。它是框架开发(如 Spring、MyBatis)、单元测试工具&a…

 的反射(Reflection)是一种强大的机制,允许程序在运行时动态获取类的信息、操作类的成员(属性、方法、构造器),甚至修改类的行为。它是框架开发(如 Spring、MyBatis)、单元测试工具(如 JUnit)的核心技术之一。

一、认识反射

反射的核心是在运行时获取类的元数据(类的结构信息),突破了传统编程 “编译时确定类型” 的限制。例如:

运行时判断任意对象的所属类;

运行时构造任意类的对象;

运行时获取 / 修改类的属性、调用类的方法(包括私有成员)

运行时处理注解。

二、Class 类详解

在  中,Class 类是反射的入口。每个类被加载到 JVM 时,会生成唯一的 Class 对象,存储该类的所有元数据(如类名、父类、接口、属性、方法等)。

2.1 获取 Class 对象的 3 种方式

// 方式1:通过 类名.class(编译时已知类)

Class<String> stringClass = String.class;

// 方式2:通过 对象.getClass()(已知对象)

String str = "hello";Class<? extends String> strClass = str.getClass();

// 方式3:通过 Class.forName("全限定类名")(动态加载,最常用)

try {

Class<?> userClass = Class.forName("com.example.User"); }

catch (ClassNotFoundException e) {

e.printStackTrace();

}

2.2 Class 类的常用方法

方法

说明

getName()

获取类的全限定名(如 .lang.String)

getSimpleName()

获取类的简单名(如 String)

getSuperclass()

获取父类的 Class 对象

getInterfaces()

获取实现的接口数组

getFields()

获取所有公有属性(含父类)

getDeclaredFields()

获取所有属性(含私有,不含父类)

getMethods()

获取所有公有方法(含父类)

getDeclaredMethods()

获取所有方法(含私有,不含父类)

getConstructors()

获取所有公有构造器

getDeclaredConstructors()

获取所有构造器(含私有)

三、Class 类与多态

多态的本质是 “父类引用指向子类对象”,但反射可以突破多态的表象,直接操作子类或父类的真实信息。

示例:通过反射获取多态对象的真实类信息
假设有继承关系:Animal(父类)→ Dog(子类)。

class Animal {

 public void eat() {

 System.out.println("Animal eat");

  } 

}

class Dog extends Animal { 

@Override 

public void eat() { 

System.out.println("Dog eat"); 

}

 }

public class PolymorphismDemo {

    public static void main(String[] args) {

        Animal animal = new Dog(); // 多态:父类引用指向子类对象

        

        // 传统方式调用方法(表现多态)

        animal.eat(); // 输出:Dog eat

        

        // 反射获取真实类的信息

        Class<?> realClass = animal.getClass(); 

        System.out.println("真实类名:" + realClass.getSimpleName()); // 输出:Dog

        

        // 反射调用父类的方法(绕过多态)

        try {

            Method parentEat realClass.getSuperclass().getMethod("eat");

            parentEat.invoke(animal); // 输出:Animal eat(调用了父类的原始方法)

        } catch (Exception e) {

            e.printStackTrace();

        }

}

}

输出结果:

Dog eat

真实类名:Dog

Animal eat

四、反射创建类对象

通过反射可以动态创建类的实例,即使类的构造器是私有的(需设置 setAccessible(true))。

4.1 无参构造创建对象

class User {

    private String name;

    public User() { System.out.println("无参构造被调用"); }

public User(String name) { this.name = name; }

}

public class CreateObjectDemo {

    public static void main(String[] args) {

        try {

            // 1. 获取User的Class对象

            Class<?> userClass = Class.forName("com.example.User");

            

            // 2. 通过无参构造创建实例(等价于 new User())

            User user = (User) userClass.getDeclaredConstructor().newInstance();

        } catch (Exception e) {

            e.printStackTrace();

        }

}

}

输出:无参构造被调用

4.2 有参构造创建对象

public class CreateObjectWithArgsDemo {

    public static void main(String[] args) {

        try {

            Class<?> userClass = Class.forName("com.example.User");

            

            // 获取有参构造器(参数类型为String)

            Constructor<?> constructor = userClass.getDeclaredConstructor(String.class);

            

            // 创建实例(等价于 new User("xxx"))

            User user = (User) constructor.newInstance("xxx");

        } catch (Exception e) {

            e.printStackTrace();

        }

}

}

4.3 私有构造器创建对象(突破访问限制)

class SecretClass {

private SecretClass() { System.out.println("私有构造被调用"); 

}

}

public class CreatePrivateObjectDemo {

    public static void main(String[] args) {

        try {

            Class<?> secretClass = Class.forName("com.example.SecretClass");

            

            // 获取私有构造器

            Constructor<?> privateConstructor = secretClass.getDeclaredConstructor();

            

            // 允许访问私有成员(关键!)

            privateConstructor.setAccessible(true);

            

            // 创建实例

            SecretClass instance = (SecretClass) privateConstructor.newInstance();

        } catch (Exception e) {

            e.printStackTrace();

        }

}

}

输出:私有构造被调用

五、反射调用类方法

通过反射可以调用任意对象的方法(包括私有方法),甚至可以调用未实现的方法(动态代理的基础)。

5.1 调用公有方法

class Calculator {

public int add(int a, int b) { return a + b; }

}

public class InvokeMethodDemo {

    public static void main(String[] args) {

        try {

            Calculator calc = new Calculator();

            Class<?> calcClass = calc.getClass();

            

            // 获取add方法(参数类型为int, int)

            Method addMethod = calcClass.getMethod("add", int.class, int.class);

            

            // 调用方法(等价于 calc.add(3, 5))

            int result = (int) addMethod.invoke(calc, 3, 5);

            System.out.println("计算结果:" + result); // 输出:8

        } catch (Exception e) {

            e.printStackTrace();

        }

}

}

5.2 调用私有方法(突破访问限制)

class PrivateMethodClass {

    private String formatName(String name) {

        return "Hello, " + name + "!";

}

}

public class InvokePrivateMethodDemo {

    public static void main(String[] args) {

        try {

            PrivateMethodClass obj = new PrivateMethodClass();

            Class<?> clazz = obj.getClass();

            

            // 获取私有方法(方法名、参数类型)

            Method privateMethod = clazz.getDeclaredMethod("formatName", String.class);

            

            // 允许访问私有成员

            privateMethod.setAccessible(true);

            

            // 调用方法(等价于 obj.formatName("xxx"))

            String result = (String) privateMethod.invoke(obj, "xxx");

            System.out.println(result); // 输出:Hello, xxx!

        } catch (Exception e) {

            e.printStackTrace();

        }

}

}

六、反射修改类属性

通过反射可以直接修改对象的属性值(包括私有属性),甚至绕过 setter 方法。

6.1 修改公有属性

class Book {

public String title = "默认书名";

}

public class ModifyFieldDemo {

    public static void main(String[] args) {

        try {

            Book book = new Book();

            Class<?> bookClass = book.getClass();

            

            // 获取公有属性title

            Field titleField = bookClass.getField("title");

            

            // 修改属性值(等价于 book.title = "反射详解")

            titleField.set(book, "反射详解");

            

            System.out.println(book.title); // 输出:反射详解

        } catch (Exception e) {

            e.printStackTrace();

        }

}

}

6.2 修改私有属性(突破访问限制)

class User {

    private String password = "123456";}

public class ModifyPrivateFieldDemo {

    public static void main(String[] args) {

        try {

            User user = new User();

            Class<?> userClass = user.getClass();

            

            // 获取私有属性password

            Field passwordField = userClass.getDeclaredField("password");

            

            // 允许访问私有成员

            passwordField.setAccessible(true);

            

            // 修改属性值(等价于 user.password = "new_password")

            passwordField.set(user, "new_password");

            

            // 验证修改结果

            System.out.println("新密码:" + passwordField.get(user)); // 输出:new_password

        } catch (Exception e) {

            e.printStackTrace();

        }

}

}

七、类加载器

类加载器(Class Loader)负责将 .class 文件加载到 JVM 中,生成对应的 Class 对象。 采用双亲委派模型,确保类的唯一性和安全性。

7.1 类加载器的层级

引导类加载器(Bootstrap Class Loader):加载 JDK 核心类(如 .lang.*),由 C++ 实现,无法通过  代码获取。

扩展类加载器(Extension Class Loader):加载 jre/lib/ext 目录下的 JAR 包。

应用类加载器(Application Class Loader):加载用户项目中的类(classpath 下的类)。

7.2 示例:查看类的加载器

public class ClassLoaderDemo {

    public static void main(String[] args) {

        // 获取String类的加载器(引导类加载器,输出null)

        ClassLoader stringLoader = String.class.getClassLoader();

        System.out.println("String类的加载器:" + stringLoader); // 输出:null

        

        // 获取当前类的加载器(应用类加载器)

        ClassLoader selfLoader = ClassLoaderDemo.class.getClassLoader();

        System.out.println("当前类的加载器:" + selfLoader); 

        // 输出:sun.misc.Launcher$AppClassLoader@18b4aac2

        

        // 获取应用类加载器的父加载器(扩展类加载器)

        ClassLoader parentLoader = selfLoader.getParent();

        System.out.println("父加载器:" + parentLoader); 

        // 输出:sun.misc.Launcher$ExtClassLoader@1b6d3586

}

}

7.3 双亲委派模型的作用

当加载一个类时,类加载器会先委托父类加载器尝试加载,直到引导类加载器。如果父类无法加载,才由当前类加载器加载。
好处:避免重复加载,防止核心类被篡改(如自定义 .lang.String 不会被加载)。

反射是  的 “动态之魂”,但过度使用会降低代码可读性和安全性(如破坏封装性)。实际开发中,框架(如 Spring)已封装了反射的复杂操作,开发者只需理解原理即可。建议结合源码(如 Spring 的 BeanFactory)深入学习反射的应用。

http://www.cadmedia.cn/news/12561.html

相关文章:

  • 建设监理收录网站武汉全网营销推广公司
  • 买完网站怎么建设网站ip查询站长工具
  • 网站建设综合训练的实验目的无锡网站建设
  • 筹划建设智慧海洋门户网站网络推广营销
  • 银川网站建设哪家价格低真正永久免费网站建设
  • 做国外销售都上什么网站网站seo优化心得
  • 网站建设公司名称网页生成
  • 网站建设的静态网页作业百度答主中心入口
  • 网站搭建修改收费依据武汉网站seo
  • 男女做爰高清免费视频网站网站统计分析工具的主要功能
  • 哈尔滨网站开发工作室公司推广策划
  • 龙海市建设局网站百度指数查询
  • 网站服务器租用怎么购买客源引流推广
  • 住房和城乡建设部建设司网站首页百度的网址是什么
  • 浙江省城乡住房建设部网站如何推广公司网站
  • 延庆网站建设优化seo做百度推广一个月多少钱
  • 济南信息化网站网络营销网站分析
  • 中国建设银行网站外汇电商网站建设定制
  • 旅游发展委员会建设网站的作用陕西seo关键词优化外包
  • 图文识别微信小程序是什么东莞seo排名优化
  • 政府网站建设 价格天津百度关键词推广公司
  • 山西公司响应式网站建设平台周口网站seo
  • 新手做导航网站seo提升排名技巧
  • 快速建站介绍百度直播平台
  • 潍坊专业网站建设哪家好搜索引擎营销的基本方法
  • 免费个人网站模版下载百度竞价推广托管
  • 购物网网站建设成都网站设计
  • html购物网站源代码新闻稿发布软文平台
  • 免费的查企业的网站seo搜索引擎招聘
  • 张家界网站seo如何优化标题关键词