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

面向对象(1)

关于对象和类

  1.对象是具体的事物;类是对对象的抽象;

  2.类可以看成一类对象的模板,对象可以看成该类的一个具体实例。

  3.类是用于描述同一类型的对象的一个抽象概念,类中定义了这一类对象所应具有的共同的属性、方法。

 Java虚拟机的内存可以分为三个区域:栈stack、堆heap、方法区method area。

栈的特点如下:

  1. 栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口等)

  2. JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量等)

  3. 栈属于线程私有,不能实现线程间的共享!

  4. 栈的存储特性是“先进后出,后进先出”

  5. 栈是由系统自动分配,速度快!栈是一个连续的内存空间!

堆的特点如下:

  1. 堆用于存储创建好的对象和数组(数组也是对象)

  2. JVM只有一个堆,被所有线程共享

  3. 堆是一个不连续的内存空间,分配灵活,速度慢!

方法区(又叫静态区)特点如下:

  1. JVM只有一个方法区,被所有线程共享!

  2. 方法区实际也是堆,只是用于存储类、常量相关的信息!

  3. 用来存放程序中永远是不变或唯一的内容。(类信息【Class对象】、静态变量、字符串常量等)

面向对象内存过程分析:

构造器也叫构造方法(constructor),用于对象的初始化。构造器是一个创建对象时被自动调用的特殊方法,目的是对象的初始化。构造器的名称应与类的名称一致。Java通过new关键字来调用构造器,从而返回该类的实例,是一种特殊的方法。

[修饰符] 类名(形参列表){
    //n条语句
}

  

要点:

  1. 通过new关键字调用!!

  2. 构造器虽然有返回值,但是不能定义返回值类型(返回值的类型肯定是本类),不能在构造器里使用return返回某个值。

  3. 如果我们没有定义构造器,则编译器会自动定义一个无参的构造函数。如果已定义则编译器不会自动添加!

  4. 构造器的方法名必须和类名一致!

垃圾回收机制

  任何一种垃圾回收算法一般要做两件基本事情:

  1. 发现无用的对象

  2. 回收无用对象占用的内存空间。

  垃圾回收机制保证可以将“无用的对象”进行回收。无用的对象指的就是没有任何变量引用该对象。Java的垃圾回收器通过相关算法发现无用对象,并进行清除和整理。

·垃圾回收相关算法

  1. 引用计数法

  堆中每个对象都有一个引用计数。被引用一次,计数加1. 被引用变量值变为null,则计数减1,直到计数为0,则表示变成无用对象。优点是算法简单,缺点是“循环引用的无用对象”无法被识别。

【示例4-7】循环引用示例  

public class Student {
    String name;
    Student friend;
     
    public static void main(String[] args) {
        Student s1 = new Student();
        Student s2 = new Student();
         
        s1.friend = s2;
        s2.friend = s1;        
        s1 = null;
        s2 = null;
    }
}

  

  s1和s2互相引用对方,导致他们引用计数不为0,但是实际已经无用,但无法被识别。

  2. 引用可达法(根搜索算法)

  程序把所有的引用关系看作一张图,从一个节点GC ROOT开始,寻找对应的引用节点,找到这个节点以后,继续寻找这个节点的引用节点,当所有的引用节点寻找完毕之后,剩余的节点则被认为是没有被引用到的节点,即无用的节点。

分代垃圾回收机制

是基于这样一个事实:不同的对象的生命周期是不一样的。因此,不同生命周期的对象可以采取不同的回收算法,以便提高回收效率。我们将对象分为三种状态:年轻代、年老代、持久代。JVM将堆内存划分为 Eden、Survivor 和 Tenured/Old 空间。

  1. 年轻代

  所有新生成的对象首先都是放在Eden区。 年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象,对应的是Minor GC,每次 Minor GC 会清理年轻代的内存,算法采用效率较高的复制算法,频繁的操作,但是会浪费内存空间。当“年轻代”区域存放满对象后,就将对象存放到年老代区域。

  2. 年老代

  在年轻代中经历了N(默认15)次垃圾回收后仍然存活的对象,就会被放到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象。年老代对象越来越多,我们就需要启动Major GC和Full GC(全量回收),来一次大扫除,全面清理年轻代区域和年老代区域。

  3. 持久代

  用于存放静态文件,如Java类、方法等。持久代对垃圾回收没有显著影响。

1.png

图4-7 堆内存的划分细节

  ·Minor GC:

  用于清理年轻代区域。Eden区满了就会触发一次Minor GC。清理无用对象,将有用对象复制到“Survivor1”、“Survivor2”区中(这两个区,大小空间也相同,同一时刻Survivor1和Survivor2只有一个在用,一个为空)

  ·Major GC:

  用于清理老年代区域。

  ·Full GC:

  用于清理年轻代、年老代区域。 成本较高,会对系统性能产生影响。

垃圾回收过程:

    1、新创建的对象,绝大多数都会存储在Eden中,

    2、当Eden满了(达到一定比例)不能创建新对象,则触发垃圾回收(GC),将无用对象清理掉,

           然后剩余对象复制到某个Survivor中,如S1,同时清空Eden区

    3、当Eden区再次满了,会将S1中的不能清空的对象存到另外一个Survivor中,如S2,

          同时将Eden区中的不能清空的对象,也复制到S1中,保证Eden和S1,均被清空。

    4、重复多次(默认15次)Survivor中没有被清理的对象,则会复制到老年代Old(Tenured)区中,

    5、当Old区满了,则会触发一个一次完整地垃圾回收(FullGC),之前新生代的垃圾回收称为(minorGC)

 java的传参机制

        是值传递。Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本。指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用的副本)是永远不会改变的。

 

  Java参数,不管是原始类型还是引用类型,传递的都是副本(有另外一种说法是传值,但是说传副本更好理解吧,传值通常是相对传址而言)。

 

  如果参数类型是原始类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,这个跟之前所谈的传值是一样的。如果在函数中改变了副本的值不会改变原始的值.

 

  如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址。如果在函数中没有改变这个副本的地址,而是改变了地址中的 值,那么在函数内的改变会影响到传入的参数。如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,此时传入的参数还是指向原来的 地址,所以不会改变参数的值。

包:

 我们通过package实现对类的管理,package的使用有两个要点:

  1. 通常是类的第一句非注释性语句。

  2. 包名:域名倒着写即可,再加上模块名,便于内部管理类。

注意事项:

  1. 写项目时都要加包,不要使用默认包。

  2. com.gao和com.gao.car,这两个包没有包含关系,是两个完全独立的包。只是逻辑上看起来后者是前者的一部分。

 如果我们要使用其他包的类,需要使用import导入,从而可以在本类中直接通过类名来调用,否则就需要书写类的完整包名和类名。import后,便于编写代码,提高可维护性。

注意要点:

  1. Java会默认导入java.lang包下所有的类,因此这些类我们可以直接使用。

  2. 如果导入两个同名的类,只能用包名+类名来显示调用相关类: 

1
java.util.Date date  = new  java.util.Date();

 静态导入(static import)是在JDK1.5新增加的功能,其作用是用于导入指定类的静态属性,这样我们可以直接使用静态属性。

【示例4-16】静态导入的使用  

1
2
3
4
5
6
7
8
9
10
11
package cn.sxt;
  //以下两种静态导入的方式二选一即可
import static java.lang.Math.*;//导入Math类的所有静态属性
import static java.lang.Math.PI;//导入Math类的PI属性
 
public class Test2{
     public static void main(String [] args){
         System.out.println(PI);
         System.out.println(random());
     }
}

 

转载于:https://www.cnblogs.com/Treesir/p/9985342.html

相关文章:

  • 阿里云视频直播API签名机制源码
  • 奇怪的事
  • java中使用lambda简化代码
  • 设计要做到扩展性强还挺难的
  • 云宏与英特尔携手发布了可全面兼容主流虚拟化解决方案
  • 收集 Kubernetes 资源统计数据的新工具
  • 从零开始搭建物联网平台(7):使用Vue编写前端页面
  • Java 面向对象之构造方法
  • 我与Jetbrains的这些年
  • input实现文字超出省略号功能
  • 复习Javascript专题(四):js中的深浅拷贝
  • stackoverflow:为什么排序后的数组要比未排序数组运行快3倍以上?
  • 胡小林:把日常生活中碰到的事变成我们发露忏悔的机会
  • 分布式消息队列 Kafka
  • 网站如何做好SEO优化,该怎么选择SEO软件?
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • angular2 简述
  • express.js的介绍及使用
  • HashMap剖析之内部结构
  • Java,console输出实时的转向GUI textbox
  • Java新版本的开发已正式进入轨道,版本号18.3
  • MySQL QA
  • NSTimer学习笔记
  • PHP 小技巧
  • redis学习笔记(三):列表、集合、有序集合
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • elasticsearch-head插件安装
  • HanLP分词命名实体提取详解
  • 如何用纯 CSS 创作一个菱形 loader 动画
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • ​软考-高级-系统架构设计师教程(清华第2版)【第20章 系统架构设计师论文写作要点(P717~728)-思维导图】​
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • $(document).ready(function(){}), $().ready(function(){})和$(function(){})三者区别
  • (javascript)再说document.body.scrollTop的使用问题
  • (SpringBoot)第七章:SpringBoot日志文件
  • (办公)springboot配置aop处理请求.
  • (二)c52学习之旅-简单了解单片机
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • (转) RFS+AutoItLibrary测试web对话框
  • .NET 6 在已知拓扑路径的情况下使用 Dijkstra,A*算法搜索最短路径
  • .NET Core 和 .NET Framework 中的 MEF2
  • .NET Core中Emit的使用
  • .Net面试题4
  • @四年级家长,这条香港优才计划+华侨生联考捷径,一定要看!
  • [ Algorithm ] N次方算法 N Square 动态规划解决
  • [1127]图形打印 sdutOJ
  • [2016.7 Day.4] T1 游戏 [正解:二分图 偏解:奇葩贪心+模拟?(不知如何称呼不过居然比std还快)]
  • [2018][note]用于超快偏振开关和动态光束分裂的all-optical有源THz超表——
  • [Android] Android ActivityManager
  • [Angular] 笔记 21:@ViewChild
  • [autojs]autojs开关按钮的简单使用
  • [autojs]逍遥模拟器和vscode对接