您的位置:首页 > 编程语言 > Java开发

1、Java对象(字节码对象、实例对象)、特性(封装、继承、多态)、类加载

2020-07-12 17:24 204 查看

字节码对象

每个类在加载(将类读到内存)时都会创建一个字节码对象,且这个对象在一个JVM内存中是唯一的.此对象中存储的是类的结构信息.

//方式1
Class<Object> c1=Object.class;
Class<Object> c2=Object.class;
System.out.println(c1==c2);
//方式2 (这里的?表示泛型通配符)
Class<?> c3=
Class.forName("java.lang.Object");
System.out.println(c2==c3);//true
//方式3
Class<?> c4=new Object().getClass();

实例对象

如何理解类的实例对象(类的对象)
1、客观事务在内存中的呈现
2、类的实例对象在同一个JVM内存中可以有多份.

Java中对象的创建方式
1、通过new关键字创建
2、通过反射创建。

Java中对象的作用?
1、存储数据
2、执行业务逻辑

JAVA对象的四大特性

  1. 核心特性:封装,继承,多态
  2. 扩展特性:组合,例如圆(Circle)中有圆心(Point)

封装

  1. 广义封装:一个项目有哪些系统构成,一个系统由哪些模块构成,…
  2. 狭义封装:对象属性私有化,方法能公开则公开.

继承

  1. 优势:实现代码的复用,提高程序的扩展性.
  2. 劣势:大范围扩展可能会导致类爆炸,会降低代码的可维护性.

多态

  1. 编译时多态:方法的重载
  2. 运行时多态:同一个行为(方法),因对象不同表现结果可能不同.

说明:此特性基于继承特性,父类引用可以指向子类对象,基于此特性可以更好实现程序之间的解耦合,提高程序可扩展性

扩展特性
组合特性可以理解为面向对象中的一个扩展特性,即可多个对象通过相互关联(协同),共同完成一个业务模块功能.

为什么要组合(相互关联)呢?

  1. 类设计时要遵循单一职责原则,即类设计时不要设计大而全的对象,对象职 责越多引起类变化的原因就会更多。
  2. 类设计要各司其职,各尽所能,这样可扩展性和维护性都会比较好

程序或框架中的组合:

  1. 如何执行一个JDBC操作?(Connection,Statement,ResultSet相互组合)
  2. 如何完成一个MyBatis操作?(SqlSessionFactory,SqlSession,Executor,.)
  3. Spring框架可以理解为一个资源整合框架,通过资源整合(组合)完成具体的业务功能

类加载过程

类的完整生命周期

类加载过程

类加载时机

主动加载

(1)使用new实例化对象时,读取和设置类的静态变量、静态非字面值常量
(静态字面值常量除外)时,调用静态方法时。
(2)对内进行反射调用时。
(3)当初始化一个类时,如果父类没有进行初始化,需要先初始化父类。
(4)启动程序所使用的main方法所在类
(5)当使用1.7的动态语音支持时

被动加载

(1)通过子类引用父类的静态字段,只会触发父类的初始化,而不会触发子类的初始化。
(2)定义对象数组和集合,不会触发该类的初始化
(3)类A引用类B的static final常量不会导致类B初始化
(注意静态常量必须是字面值常量,否则还是会触发B的初始化)
(4)通过类名获取Class对象,不会触发类的初始化。如System.out.println(Person.class);
(5)通过Class.forName加载指定类时,如果指定参数initialize为false时,也不会触发类初始化。
(6)通过ClassLoader默认的loadClass方法,也不会触发初始化动作

注意:被动引用不会导致类初始化,但不代表类不会经历加载、验证、准备阶段

类加载方式

隐式加载

1、创建类对象
2、使用类的静态域
3、创建子类对象
4、使用子类的静态域
5、在JVM启动时,BootStrapLoader会加载一些JVM自身运行所需的class
6、在JVM启动时,ExtClassLoader会加载指定目录下一些特殊的class
7、在JVM启动时,AppClassLoader会加载classpath路径下的class,
以及main函数所在的类的class文件

显式加载

1、ClassLoader.loadClass(className),只加载和连接、不会进行初始化
2、Class.forName(String name, boolean initialize,ClassLoader loader);
使用loader进行加载和连接,根据参数initialize决定是否初始化。

参考文档
1、https://www.geek-share.com/detail/2728414908.html
2、https://blog.csdn.net/zhaocuit/article/details/93038538

类加载器

根据一个类的全限定名来读取此类的二进制字节流到JVM中,然后转换为一个与目标类对应的java.lang.Class对象实例
虚拟机提供了3种类加载器
1、引导(Bootstrap)类加载器(C++语言实现)

虚拟机的一部分,主要加载<JAVA_HOME>/lib中的核心类库或-Xbootclasspath指定路径下的jar包

2、扩展(Extension)类加载器(Java语言实现)

Launcher的静态内部类,加载<JAVA_HOME>/lib/ext或者-Djava.ext.dir指定位路径中的类库

3、系统(System)类加载器(也称应用类加载器)

加载系统类路径java -classpath或-D java.class.path 指定路径下的类库,
开发者可以直接使用系统类加载器,一般情况下该类加载是程序中默认的类加载器,
通过ClassLoader.getSystemClassLoader()方法可以获取到该类加载器

4、自定义类加载器

系统的ClassLoader只会加载指定目录下的class文件
如果需要根据特定的需求去加载类,就需要自定义类加载器,框架和中间件中都有自定义加载器
自定义方式:新建一个类继承自java.lang.ClassLoader

参考文档
1、https://www.geek-share.com/detail/2709440848.html
2、https://blog.csdn.net/huazai30000/article/details/85296671

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: