java面向对象之类

概述

类是对有着相同特征对象的统称,对象是类的具体化。

类的写法

public class Human{
    public String name;
    public void say(){
        System.out.println("你好!");
}
}

类的实例化

public static void main(String[] args){
    Human it = new Human();
    it.Name = "cgy";
    it.Say();
}

匿名调用

public static void main(String[] args){
    new Human().say();
}

类的作用

类里面三种东西:字段(成员变量)、方法(函数)、属性(特殊的方法)

成员变量:类里、方法外
静态变量:类里、方法外
局部变量:方法内

它像一个模板
自定义类可以用多个属性描述出一类事物的模型
表如调查表:有学生调查表、职员调查表。
两张表,需要你填写的填写项是不一样的,这个填写项就是字段
学生表:姓名、年龄、所属学校
职员表:姓名、年龄、所属公司
每张表被填写完了以后,就能用里面的字段,描述出这一类人不同的特点

类的注意事项

1、一个class文件可以有多个类,但只能有一个public的类
2、public的类名必须与文件名相一致
3、如果类名和文件名一致,但是他没写public,就默认是public
4、一个class文件里,必须有一个类名和文件名一样
5、先后顺序:package>import>class

类之间的关系

IS-A 继承:
父类与子类,具有很高的耦合度
耦合度:模块间联系越多,其耦合性越强、独立性越差

HAS-A 组合:
是整体与部分的关系,同时它们的生命周期都是一样的

USE-A 依赖:
其中一个拥有另外一个但是不负责销毁,也就是生命周期不一样

内存的六大区

栈内存:
栈内存最大的特点是内部数据的生命周期都很短
数据在生命周期结束之后,自动释放内存空间
主要用于存放对象名(Human h001的h001)
引用名(String a的a)
基本类型(short int long)
方法的参数(是引用名或基本类型)
分配的内存量有限,一般就是2M,是连续的一片空间
栈仅允许在表的一端进行插入和删除操作,这一端被称为栈顶
相对地,把另一端称为栈底
栈就是一个桶,后放进去的先拿出来
下面的东西,要等上面的出来之后才能出来(先进后出)

堆内存:
用于存储数组、对象(new出来的类)、引用指向的实体
相对栈内存而言,这片内存内的数据的生命周期就由程序员进行指定
当堆内部实体不再被指向之后,并且程序员没有控制它
这片空间就会不定时的被Java垃圾回收机制所回收
堆是在程序运行时,申请内存空间的,而不是在程序编译时,所以是动态分配
在内存中的空间是不连续的
引用类型保存的是一个,指向堆区的指针
通过这个指针,就可以找到这个实例在堆区对应的对象

静态区:
全局变量和静态变量的存储是放在一块的
程序结束后由系统释放
存放类中以static声明的静态成员变量
静态成员属于整个类,不属于某个对象
访问:class.StaticField
静态方法的效率上要比实例化高
静态方法的缺点是不自动进行销毁,而实例化的则可以做销毁

方法区:
是各个线程共享的内存区域,它用于存储class二进制文件
包含了虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据
它有个名字叫做Non-Heap(非堆),与Java堆区分开。

常量池:
常量池是方法区的一部分内存
常量存储在这里,不允许修改,可读不可写
在编译的阶段,在堆中分配出来的一块存储区域
用于存储显式的String
显式:String str="abc"; abc这个字符串是显式声明

寄存器:
最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制

队列:
队列是一种特殊的、受限制线性表
特殊之处在于它只允许在表的前端进行删除操作
而在表的后端进行插入操作
队列中没有元素时,称为空队列。
建立队列结构,必须为其申请一片连续的存储空间
并设置两个指针进行管理。一个是队头指针,它指向队头元素
另一个是队尾指针,它指向下一个入队元素的存储位置。(先进先出)

内存分析:
Human h = new Human();
h.Name = “Jenny”;
h.Age = 17;

栈内存存放:h 
堆内存存放:new Human();  new Human里包含了Name

成员属性,是有默认初始值的。
int默认值0  double默认值0.0  char默认值’’
String默认值null  引用类型默认值null
对象一创建new Human(),成员变量也会默认分配初始值
Name Age的整体有一个地址比如叫0x97,就把栈中的h绑定了0x97的地址
所以他们就关联起来了。
h.Name = “Jenny”;赋值后,就把默认值改成了Jenny
面试题:String s = new String(“xyz”);创建了几个对象?
一个是xyz,一个是指向xyz的s

枚举

为了使变量的值标准化,所以提前定义好了变量

enum Weekday { //类级别
    SUN, MON, TUE, WED, THU, FRI, SAT;
}
System.out.println(Weekday.SAT);

类的加载过程

类加载器过程:加载、连接(验证、准备、解析)、初始化

加载阶段过程:
1、通过一个类的全限定名来获取此类的二进制字节流
获取一个类的二进制字节流(即.class文件)的方法有:
从ZIP包中读取、从网络中获取、动态代理技术、从数据库中读取等

2、将这个字节流所代表的静态存储结构,转化为方法区的运行时数据结构
加载的过程中主要由类加载器来完成。类加载器也分为不同种类
JVM自带的类加载器,用户也可以使用自己定义的类加载器

3、在内存中生成一个代表这个类的java.lang.Class对象
作为方法区这个类的各种数据的访问入口

连接 > 验证阶段过程:
验证是连接阶段的第一步
这一阶段的主要目的是为了确保Class文件的字节流
包含的信息符合当前虚拟机的要求
保证不会危害虚拟机自身的安全
验证阶段是非常重要的,这个阶段是否严谨
直接决定了Java虚拟机是否能够承受恶意代码的攻击
从执行性能的角度上讲,验证阶段的工作量在虚拟机的
类加载子系统中又占据了相当大的一部分
此阶段主要包含如下几个部分的验证:
1.文件格式验证 2.元数据验证 3.字节码验证 4.符号引用验证

连接 > 准备阶段过程:
准备阶段是正式为类变量分配内存并设置类变量初始值的阶段
这些变量使用的内存都将在方法区中进行分配
准备阶段是为类变量分配内存并设置初始值而不是实例变量
类变量属于class,实例变量属于方法
实例变量将会在对象实例化时随着对象一起被分配在Java堆中

连接 > 解析阶段过程:
解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程
解析主要包括:
1.类或接口的解析 2.字段解析 3.类方法解析 4.接口方法解析

初始化阶段过程:
类初始化阶段是类加载过程的最后一步,前面的类加载过程中
除了在加载阶段用户应用程序可以通过自定义类加载器参与之外
其余动作完全由虚拟机主导和控制
到了初始化阶段,才真正开始执行类中定义的Java程序代码(字节码)
将一个类中所有被static关键字标识的代码统一执行一遍
如果父类还没有被初始化,那么优先对父类初始化
初始化对于类来说,就是执行类构造器<clinit>方法的过程
<clinit>:在jvm第一次加载class文件时调用
包括静态变量初始化语句和静态块的执行
创建类的实例,也就是new的方式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值