JAVA重要知识!反射!

1 篇文章 0 订阅
今天重新学习了一下反射,比刚开始学习的时候轻松了许多。所以如果你是第一次学习反射,不要害怕,就当是自己预习了。等你学习第二遍的时候,你肯定就会轻而易举的理解当时死活看不懂的知识了。

既然说到了反射,就先说一说我们普通的创建对象的过程吧。
假如有一个类Person

Person p = new Person();

这一步创建对象的过程是分了三小步!
1.生命变量p (变量p存放在栈内存中)
2.开始new Person(),位对象分配内存空间。(在堆内存中分配)
3.指针移位。将堆内存中的地址,分配给栈p,让p指向内存。


上面说了我们普通创建对象的过程。下面来看一看这个反射到底是个什么玩意儿!

new对象 : 是先有类,然后通过类去创建对象。
反射 : 反射是知道了类的全路径,然后通过类的全路径去获得类的实例

我们常用的new对象可以理解为辛勤劳作的劳苦大众!
而反射,则可以理解为空手套白狼的坏蛋,知道了类的全路径,就把能搞到一个对象

所以,反射其实是破坏了面向对象的封装的!

但是呢!反射的作用确实很大。下面我们来一起看一下。

首先理解一下什么是Class类。
注意:此处的Class中首字母是大写的,指的是一个类,而不是我们经常说的class(关键字)!

Class类的作用:Class类,是类的描述符。它比较特殊:没有公有构造函数,所以不能new对象。


下面来看看反射是怎么通过类的全路径创建对象的。

public class Test {
    public static void main(String[] args) throws Exception{
        Class<Demo> clazz =Class.forName("com.myproject.Demo");
        Demo demo = clazz.newInstance();
    }

}

反射就是Class类通过Person的描述符创建一个Class类的对象。然后通过calzz调用newInstance()方法来创建Person对象的实例。


此处先说明一个反射牛逼的功能:
当我们的一个构造器是被private修饰的时候,我们仍然可以调用这个构造函数。只要给这个构造器设置一个可访问的属性即可!

例如Demo的构造函数是私有的:如下:

public class Demo {
    private Demo(){
        System.out.println("这是默认的构造函数");
    }
}

获取Demo私有的构造函数,来创建对象

   @Test
    public void test() throws Exception{
        Class<Demo> clazz = Demo.class;
        Constructor constroctor = clazz.getDeclaredConstructor();
        //这一句话起到了重要作用!!!!
        constroctor.setAccessible(true);
        constroctor.newInstance();
    }

只要将构造器的这个方法设置为true即可访问私有的构造函数。

然而此时的构造函数仍然是私有的,只不过该方法只是将方法区中的状态更改了,跟字节码没有关系。



上面说的是反射创建对象,下面来贴出反射调用方法的代码:

显示Demo类的代码:

public class Demo {
    public Demo(){
        System.out.println("这是默认的构造函数");
    }

    public void fun(String name){
        System.out.println("这是普通方法"+name);
    }
}

然后是反射类的代码:

public class ReflectDemo {
    @Test
    public void test() throws Exception{
        Class<Demo> clazz = Demo.class;
        Demo demo = clazz.newInstance();
        Method method = clazz.getDeclaredMethod("fun",String.class);
        method.invoke(demo,"haha");
    }
}

通过反射调用方法,是通过先获取方法的对象,然后通过invoke方法来调用。

但是有一点我们好奇,既然invoke方法中传入了demo对象,为什么不直接使用demo对象直接调用fun()方法呢???

本人初学者,请大神赐教

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java是一种广泛使用的面向对象的编程语言,由Sun Microsystems公司于1995年5月正式发布。它的设计目标是“一次编写,到处运行(Write Once, Run Anywhere)”,这意味着开发者可以使用Java编写应用程序,并在支持Java的任何平台上无需重新编译即可运行,这得益于其独特的跨平台性,通过Java虚拟机(JVM)实现不同操作系统上的兼容。 Java的特点包括: 面向对象Java面支持面向对象的特性,如封装、继承和多态,使得代码更易于维护和扩展。 安Java提供了丰富的安特性,如禁止指针运算、自动内存管理和异常处理机制,以减少程序错误和恶意攻击的可能性。 可移植性:Java字节码可以在所有安装了JVM的设备上执行,从服务器到嵌入式系统,再到移动设备和桌面应用。 健壮性与高性能:Java通过垃圾回收机制确保内存的有效管理,同时也能通过JIT编译器优化来提升运行时性能。 标准库丰富:Java拥有庞大的库,如Java SE(Java Standard Edition)包含基础API,用于开发通用应用程序;Java EE(Java Enterprise Edition)提供企业级服务,如Web服务、EJB等;而Java ME(Java Micro Edition)则针对小型设备和嵌入式系统。 社区活跃:Java有着球范围内庞大的开发者社区和开源项目,持续推动技术进步和创新。 多线程支持:Java内建对多线程编程的支持,使并发编程变得更加简单直接。 动态性:Java可以通过反射、注解等机制实现在运行时动态加载和修改行为,增加了程序的灵活性。 综上所述,Java凭借其强大的特性和广泛的适用范围,在企业级应用、互联网服务、移动开发等领域均扮演着举足轻重的角色,是现代软件开发不可或缺的重要工具之一。
面试必备,java基础、java集合、JVM、Java并发、数据结构与算法、LeetCode、剑指offer、计算机网络、设计模式、MySQL、Redis Java是一种广泛使用的面向对象的编程语言,由Sun Microsystems公司于1995年5月正式发布。它的设计目标是“一次编写,到处运行(Write Once, Run Anywhere)”,这意味着开发者可以使用Java编写应用程序,并在支持Java的任何平台上无需重新编译即可运行,这得益于其独特的跨平台性,通过Java虚拟机(JVM)实现不同操作系统上的兼容。 Java的特点包括: 面向对象Java面支持面向对象的特性,如封装、继承和多态,使得代码更易于维护和扩展。 安Java提供了丰富的安特性,如禁止指针运算、自动内存管理和异常处理机制,以减少程序错误和恶意攻击的可能性。 可移植性:Java字节码可以在所有安装了JVM的设备上执行,从服务器到嵌入式系统,再到移动设备和桌面应用。 健壮性与高性能:Java通过垃圾回收机制确保内存的有效管理,同时也能通过JIT编译器优化来提升运行时性能。 标准库丰富:Java拥有庞大的库,如Java SE(Java Standard Edition)包含基础API,用于开发通用应用程序;Java EE(Java Enterprise Edition)提供企业级服务,如Web服务、EJB等;而Java ME(Java Micro Edition)则针对小型设备和嵌入式系统。 社区活跃:Java有着球范围内庞大的开发者社区和开源项目,持续推动技术进步和创新。 多线程支持:Java内建对多线程编程的支持,使并发编程变得更加简单直接。 动态性:Java可以通过反射、注解等机制实现在运行时动态加载和修改行为,增加了程序的灵活性。 综上所述,Java凭借其强大的特性和广泛的适用范围,在企业级应用、互联网服务、移动开发等领域均扮演着举足轻重的角色,是现代软件开发不可或缺的重要工具之一。
Java反射Java语言的一项重要特性,它允许程序在运行时动态地获取并操作对象、方法和属性的信息。下面列出了Java反射的一些重要知识点: 1. Class:Class反射的核心,它表示一个的信息,包括的名称、构造函数、方法和字段等。 2. 获取Class对象:可以通过以下方式获取Class对象: - 使用名.class语法:例如,String.class表示String的Class对象。 - 使用对象的getClass()方法:例如,"Hello".getClass()返回String的Class对象。 - 使用Class.forName()方法:例如,Class.forName("java.lang.String")返回String的Class对象。 3. 获取的构造函数:可以使用getConstructors()、getConstructor()等方法获取的构造函数信息。 4. 获取的方法:可以使用getMethods()、getMethod()等方法获取中定义的方法信息。 5. 获取的字段:可以使用getFields()、getField()等方法获取中定义的字段信息。 6. 创建对象:可以使用newInstance()方法创建一个实例。 7. 调用方法:可以使用Method对象的invoke()方法调用一个方法。 8. 访问字段:可以使用Field对象的get()和set()方法读取和设置一个字段的值。 9. 修改访问权限:可以使用setAccessible()方法修改私有成员的访问权限。 10. 获取父和接口:可以使用getSuperclass()方法获取一个的父,使用getInterfaces()方法获取一个实现的接口。 11. 动态代理:可以使用Proxy和InvocationHandler接口创建代理对象,实现对目标对象的动态代理。 这些是Java反射的一些重要知识点,通过反射,可以在运行时动态地获取和操作的信息,从而实现一些灵活的编程逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值