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

[Java]反射、String类补充

目录

1、反射定义

2、用途(了解)

3、反射相关的类

4、Class类(反射机制的起源)

4.1、相关方法

5、反射示例

5.1、获取Class对象

5.2、反射的使用

6、反射优点和缺点

7、String类补充

7.1、创建对象的思考

8、字符串常量池

9、再谈String对象创建

10、intern方法


1、反射定义

Java的反射(reflection)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,既然能拿到那么,我们就可以修改部分类型信息;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射(reflection)机制

反射基本信息:

Java程序中许多对象在运行时会出现两种类型:运行时类型(RTTI)和编译时类型,例如Person p = new Student();这句代码中p在编译时类型为Person,运行时类型为Student。程序需要在运行时发现对象和类的真实 信息。而通过使用反射程序就能判断出该对象和类属于哪些类

2、用途(了解)

1. 在日常的第三方应用开发过程中,经常会遇到某个类的某个成员变量、方法或是属性是私有的或是只对系统应用开放,这时候就可以利用Java的反射机制通过反射来获取所需的私有成员或是方法 。

2. 反射最重要的用途就是开发各种通用框架,比如在spring中,我们将所有的类Bean交给spring容器管理,无 论是XML配置Bean还是注解配置,当我们从容器中获取Bean来依赖注入时,容器会读取配置,而配置中给的 就是类的信息,spring根据这些信息,需要创建那些Bean,spring就动态的创建这些类。

3、反射相关的类

4、Class类(反射机制的起源)

Class类:代表类的实体,在运行的Java应用程序中表示类和接口

Java文件被编译后,生成了.class文件,JVM此时就要去解读.class文件 ,被编译后的Java文件.class也被JVM解析为一个对象,这个对象就是 java.lang.Class .这样当程序在运行时,每个java文件就最终变成了Class类对象的一个实例。

我们通过Java的反射机制应用到这个实例,就可以去获得甚至去添加改变这个类的属性和动作,使得这个类成为一个动态的类

4.1、相关方法

(重要)常用获得类相关的方法

(重要)常用获得类中属性相关的方法(以下方法返回值为Field)

(了解)获得类中注解相关的方法(以下方法返回值为Constructor)

(重要)获得类中方法相关的方法(以下方法返回值为Method)

5、反射示例

以Student类为例

package demo1;class Student {//私有属性nameprivate String name = "bit";//公有属性agepublic int age = 18;//不带参数的构造方法public Student(){System.out.println("Student()");}private Student(String name,int age) {this.name = name;this.age = age;System.out.println("Student(String,name)");}private void eat(){System.out.println("i am eat");}public void sleep(){System.out.println("i am pig");}private void function(String str) {System.out.println(str);}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}

5.1、获取Class对象

在反射之前,我们需要做的第一步就是先拿到当前需要反射的类的Class对象,然后通过Class对象的核心方法,达到反射的目的,即:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,既然能拿到那么,我们就可以修改部分类型信息。

(推荐前两种,不推荐第三种)
第一种,使用 Class.forName("类的全路径名"); 静态方法。
前提:已明确类的全路径名。


第二种,使用 .class 方法。
说明:仅适合在编译前就已经明确要操作的 Class


第三种,使用类对象的 getClass() 方法

c1、c2、c3都是同一个对象,得出结论:Class对象只有一个

5.2、反射的使用

依旧反射上面的Student类

注意:所有和反射相关的包都在 import java.lang.reflect 包下面

1. 创建对象

2. 反射私有的构造方法

3. 反射私有属性  (name)

4. 反射私有方法  (function)

6、反射优点和缺点

优点:
1. 对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法
2. 增加程序的灵活性和扩展性,降低耦合性,提高自适应能力
3. 反射已经运用在了很多流行框架如:Struts、Hibernate、Spring 等等。


缺点:
1. 使用反射会有效率问题。会导致程序效率降低。比如说,为了调用一个方法,调用了五个方法,五个方法才相当于一个方法,效率必然不高。具体参考这里:http://www.imooc.com/article/293679
2. 反射技术绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂


7、String类补充

7.1、创建对象的思考

下面两种创建String对象的方式相同吗?

上述程序创建方式类似,为什么s1和s2引用的是同一个对象,而s3和s4不是呢?

在Java程序中,类似于:1, 2, 3,3.14,“hello”等字面类型的常量经常频繁使用,为了使程序的运行速度更快、 更节省内存,Java为8种基本数据类型和String类都提供了常量池

为了节省存储空间以及程序的运行效率,Java中引入了:
1. Class文件常量池:每个.Java源文件编译后生成.Class文件中会保存当前类中的字面常量以及符号信息
2. 运行时常量池:在.Class文件被加载时,.Class文件中的常量池被加载到内存中称为运行时常量池,运行时常量池每个类都有一份
3. 字符串常量池

8、字符串常量池

字符串常量池在JVM中是StringTable类,实际是一个固定大小的HashTable(哈希表),不同JDK版本下字符串常量池的位置以及默认大小是不同的:

9、再谈String对象创建

String对象创建的底层逻辑:String s3 = new String("world");

只要是双引号引起来的都会存放在常量中

1. 当s1创建完成后,再创建s2,先去常量池查找是否有当前这个字符串,如果有,会把常量池中这个对象的地址给到s2。这样一来,s1和s2都指向了同一个对象,所以打印 s1==s2 的返回值一定为true


2. 创建 s3 = new String("world"),首先在常量池中查找是否有world这个字符串,没有就跟 s1 一样就存放到常量池中;再创建一个新对象 s4 = new String("world"),首先在常量池中找到了world这个字符串,此时会new一个新的String对象,然后把存放world字符串的地址给到新对象的 value


结论:

1. 常量池中有,就用常量池里的;常量池中没有,就把它放到常量池

2. 只要是new的对象,都是唯一的。

通过上面例子可以看出:使用常量串创建String类型对象的效率更高,而且更节省空间。

也可以将创建的字符串对象通过 intern 方式添加进字符串常量池中。

10、intern方法

先分析这段代码

它的底层存储:

1. 创建 s1= new String(ch),参数ch不是双引号引起来的,所以不放到常量池,它的存储方式是:new一个新对象,其中的value指向拷贝后的新数组

2. s2 = "abc",abc是双引号引起来的,所以放到常量池;

3. 综上,s1和s2没有任何关系,所以这段代码的结果为false

intern方法:让s1所指向的对象入池;如果常量池中存在,就不入池

s1入池后,创建s2 = "abc",在常量池找到了这个字符串,最终s1和s2指向的是同一个对象,所以加上intern方法后,代码执行结果为true

public static void main(String[] args) {char[] ch = new char[]{'a', 'b', 'c'};String s1 = new String(ch); // s1对象并不在常量池中//s1.intern(); // s1.intern();调用之后,会将s1对象的引用放入到常量池中String s2 = "abc"; // "abc" 在常量池中存在了,s2创建时直接用常量池中"abc"的引用System.out.println(s1 == s2);
}
// 输出false
// 将上述方法打开之后,就会输出true

相关文章:

  • SICAR程序标准功能块 FB1512 “Robot_kuka_FB“
  • 02、Yarn的安装理念及如何破解依赖管理困境
  • Photoshop安装与配置--简单攻略版
  • 【教程】DVWA靶场渗透
  • 【无标题】微信开发者工具编译运行没问题,真机调试报错:Component is not found in path “wx://not-found“.
  • JavaScript 中的同步与异步:从单线程到事件循环
  • 睡前小故事数据集分享
  • 企业微信自建应用开发回调事件实现方案
  • javaNIO详解
  • cv::dnn::NMSBoxes和nms-free的比较
  • 测风塔布局算法详解:基于宏观分区与微观定量选址的双阶段优化方法
  • Java数据结构——ArrayList
  • Spring 依赖冲突解决方案详解
  • SAP系统工艺路线的分配物料出现旧版包材
  • 从 0~1 保姆级 详细版 PostgreSQL 数据库安装教程
  • 理解Java一些基础(八股)
  • 红帽RHEL与国产Linux系统对比:技术、生态与自主可控的博弈
  • 如何系统地入门学习stm32?
  • 【大模型】 LangChain框架 -LangChain实现问答系统
  • [C++] 高精度加法(作用 + 模板 + 例题)
  • 《“四有”好老师系列丛书》发布,由顾明远总主编
  • 广东音像城清退,发烧友紧急“淘宝”,曾见证广州音乐黄金期
  • 普京宣布临时停火30小时
  • 撤销逾千名留学生签证,特朗普政府面临集体诉讼
  • 能源央企资产重组大提速,专业化整合掀起新热潮
  • 二手服装“批发”市集受到年轻人追捧,是哪一股潮流在推动?