发布时间:2022-11-08 文章分类:编程知识 投稿人:王小丽 字号: 默认 | | 超大 打印

一、绪论

主要参考

1.问题汇总

Q:JAVA和C++有什么区别

A:

解答1:

(18条消息) c++与java的应用区别_蓝黑墨水的博客-CSDN博客_c++和java区别

解答2:

Java和C/C++到底有什么关系?它们有什么区别? (biancheng.net)

发展历程:C -> C++ -> Java 。Java 是由 C++发展而来的,保留了 C++ 的大部分内容,其编程方式类似于 C++。但 Java 的句法更清晰、规模更小、更易学。Sun 公司曾对多种程序设计语言进行分析研究,取其精华去其糟粕,最终推出了 Java。Java 从根本上解决了 C++ 的固有缺陷,形成了新一代面向对象的程序设计语言。

解答3:

C/C++和Java确实不太一样。C语言和C++,尤其是C++,语言密度更细,机制多,性能虽然高,但是就语言本身来说,包狱太重。所以也就称之为“造轮子”的语言,但是也正是因为他性能好,密度细,所以什么都能做。而Java本身是服务于互联网软件开发(后端开发、客户端开发)的语言,他有一个明显的生态圈的概念,所以应用领域非常清晰。因为Java是纯应用层的,所以相对而言学习C++更加困难一些,对于程序员能力的要求要更高一些。C/C++的主场在系统底层;(PS:现在JAVA也很少用来做浏览器客户端的交互了,取代applet(使用JAVA编写的应用程序)的是JS和Flash等脚本语言;当然不管是C++还是JAVA都别用来写前端界面!!!)

解答4:(基于作者学过的一些语言对比)

后端逻辑使用JAVA或者Node.js(JS本身是做前端逻辑的,但是node.js是可以写后端的,但应该没多少人会这么疯狂)做都可以,C/C++更适合做底层系统相关的东西,python因为简单轻量有很多现成完善的库可以直接调用(自己写小工具也很方便)

JAVA

解答5:

(19条消息) c面向对象 java_c++面向对象和java面向对象的区别?_weixin_39584571的博客-CSDN博客

Q:为什么要学JAVA?

A:因为我想知道有关软件开发和桌面应用等知识点,我学JAVA并不是需要会用这门语言,而是需要知道这门语言和我学习中会接触到的大量知识盲区的关系,所以学习过程中不要特别在于语法条件之类的,着重看重JAVA特性和用途;

Q:为什么JAVA的项目名和什么类型这么麻烦?一旦不对应似乎整个程序都会崩溃????

A:因为JAVA是一门非常严谨的语言,任何规则都必须遵守(有句话很有意思“C++更加灵活,JAVA更加严谨”),正是因为其语法的严谨特性,所以还有一句话是“C++动不动就崩溃,JAVA想写崩溃都难”;

2.JAVA概述

按应用范围,Java 可分为 3 个体系,即 Java SE、Java EE 和 Java ME

JAVA主要有以下特性:

3.核心机制

3.1 JAVA虚拟机

JVM是一个虚拟的计算机,具有指令集并使用不同的存储区域。负责执行指令,管理数据、内存、寄存器。对于不同的平台,有不同的虚拟机。只有某平台提供了对应的java虚拟机,java程序才可在此平台运行。

JAVA

Java虚拟机机制屏蔽了底层运行平台的差别,实现了“一次编译,到处运行”;

3.2 垃圾回收机制

C/C++中需要程序员手动释放无用内存;

Java 语言消除了程序员回收无用内存空间的责任:它提供一种系统级线程跟踪存储空间的分配情况。并在JVM空闲时,检查并释放那些可被释放的存储空间。垃圾回收在Java程序运行过程中自动进行,程序员无法精确控制和干预;

尽管JAVA拥有自动垃圾回收机制,但是有时候我们写的程序可能存在问题仍将导致自动回收机制无法识别垃圾进而造成内存泄漏(某些对象申请内存没有被释放,一直占用)和内存溢出(程序所需的内存大于系统所能提供的最大内存);

4.JAVA环境

JDK(Java Development Kit Java开发工具包)JDK是提供给Java开发人员使用的,其中包含了java的开发工具,也包括了JRE。所以安装了JDK,就不用在单独安装JRE了。

JAVA

(非常幸运的是在之前安装爬虫appinum的时候安装Andriod SDK时顺便就安装了JDK环境,所以我们省略了安装JDK的步骤,教程参考(18条消息) JDK下载与安装教程_墨笙弘一的博客-CSDN博客_jdk安装教程)

PS:按照网上的JDK安装教程并没有配置安装JRM所以可能目录环境和B站老师讲的不太一样,先将就用着,期间有什么问题做记录写下来记录即可

5.JAVA标准格式

我们这里给出一个基本的JAVA程序的模板,并简单解释下相关的参数,在之后还会详细介绍

public class HelloJava {
    public static void main(String[] args){
        System.out.println(""!我的第一个 Java程序!");
    }
}

JAVA中main()方法是应用程序的入口方法,main()方法与其他方法存在很大差别:

二、JAVA基础

1.JAVA注释

//注释文字
/*注释文字*/
/**
@author 指定 java 程序的作者 **
@version 指定源文件的版本 **
*/

文档注释的内容可以被JDK提供的工具javadoc解析(包、公有类和接口、公有的和受保护的方法、公有的和受保护的域)生成一套以网页文件形式体现该程序的说明文档

javadoc -d 文件夹名 -author -version 文件名

文档注释一般用在类、方法和变量上面,用来描述其作用。注释后,鼠标放在类和变量上面会自动显示出我们注释的内容

关于JAVA文档注释的更多消息可以参考Javadoc(文档注释)详解 (biancheng.net)也可以参考《JAVA技术卷1》P137、Java注释:类、方法和字段注释 (biancheng.net)

2.JAVA运行流程

Java程序的运行过程(执行流程)分析 (biancheng.net)

JAVA

JAVA中的所有东西都会属于某个类,我们写的源文件经过编译后会得到类文件(.class,存储的字节码),被VM执行的实际是类 - 执行程序就表示命令JVM加载HelloJava这个类并开始执行它的main(),直到main的所有程序代码结束为止;

3.JAVA常量

常量是指在程序的整个运行过程中值保持不变的量。

注意:常量和常量值是不同的概念,常量值是常量的具体和直观的表现形式,常量是形式化的表现。通常在程序中既可以直接使用常量值,也可以使用常量

3.1 常量值

3.1 常量值

常量值又称字面常量,通过数据直接表示,可分为:

3.2 常量

JAVA中的常量名一般使用大写

final dataType variableName = value

final 是定义常量的关键字(实际上JAVA也有const关键字但没使用),dataType 指明常量的数据类型,variableName 是常量的名称,value 是初始值

常量分为:

public static final double PI = 3.14;

在 final 之前 public static 修饰,public static 修饰的常量作用域是全局的,不需要创建对象就可以访问它

3.3 final修饰符

final 应用于类、方法和变量时意义是不同的,但本质是一样的,都表示不可改变;

使用 final 关键字声明类、变量和方法需要注意以下几点:

4.JAVA变量

JAVA中的每一个变量都属于一种类型,声明变量时一定要声明变量所属类型;

4.1 变量

DataType identifier;//每个声明以分号结束(因为声明是一条完整的语句)
DataType identifier=value;//声明变量的同时初始化变量

C/C++中int i=10是定义一个变量,extern int i是声明一个变量,但是JAVA中并不区分变量的声明和定义;

4.2 变量作用域

变量根据作用域的不同可以分为:

成员变量和局部变量的主要不同点就在于,必须明确的初始化局部变量才能使用,而成员变量假如没有初始化则自动初始化为默认值(0、false、null)

JAVA面向对象的概念中并不存在全局变量的概念;

5.JAVA数据类型

数据类型是指编译器存储在变量中的数值应当具有适当的数据类型,JAVA是一种强数据类型的语言,必须为每一个变量声明一种类型,JAVA数据类型分为基本数据类型和引用数据类型

JAVA

5.1 基本数据类型

JAVA

5.2 引用数据类型

引用数据类型建立在基本数据类型的基础上,包括数组、类和接口。引用数据类型是由用户自定义,用来限制其他数据的类型(这一点其实非常类似C++的复合数据类型)。另外,Java 语言中不支持C++中的指针类型、结构类型、联合类型(类类型、枚举类型)。

6.JAVA流程控制

程序设计主要有三种流程结构:顺序结构、选择结构和循环结构,系统默认是自上而下以顺序结构执行;

6.1 JAVA语句

Java 中,语句是最小的组成单位,每个语句必须使用分号作为结束符

按照语句的组成部分,可将JAVA中的语句分为如下三类

6.1.1 空语句

;

空语句就是一个分号,在程序中什么也不做,主要用于做空循环体;

6.1.2 表达式语句

pi = 3.1415926;
output(pi); // 将pi的值传递到output()函数中作为参数
sum = (a+b)/2;
printf("%f",sum); // 将sum的值传递到printf()函数输出
temp = x*y*z-y+(20-x); // 将表达式的值保存到temp变量中

一般表达式语句应该能完成一个操作,如修改变量的值或者作为函数参数等

6.1.3 复合语句

{
    statement-list // 语句列表
}

复合语句(代码块/语句块)是很多语句的组合,将一个代码块/语句块看作一个语句;

6.2 选择结构

选择结构(也叫分支结构)解决了顺序结构不能判断的缺点,可以根据一个条件判断执行哪些语句块;

JAVA支持两种选择语句(使用选择语句实现选择结构):if 语句和 switch 语句,这些语句允许只有在程序运行时才能知道其状态的情况下,控制程序的执行过程

6.3 循环结构

循环语句能够使程序代码重复执行,适用于需要重复一段代码直到满足特定条件为止的情况;

JAVA中采用的循环语句与C语言中的循环语句相似,主要有 while、do-while 和 for、for-each 循环语句,for-each 循环是 for 循环的变形,它是专门为集合遍历而设计的;

6.3.1 for-each语句

for(类型 变量名:集合) {
    语句块;
}
// 声明并初始化数组
int[] numbers = { 43, 32, 53, 54, 75, 7, 10 };
System.out.println("----for----");
// for语句
for (int i = 0; i < numbers.length; i++) {
    System.out.println("Count is:" + numbers[i]);
}
// 声明并初始化int数组
int[] numbers = { 43, 32, 53, 54, 75, 7, 10 };
System.out.println("----for each----");
// for-each语句
for (int item : numbers) {
    System.out.println("Count is:" + item);
}

foreach 循环和普通循环不同的是,它无须循环条件,无须循环迭代语句,这些部分都由系统来完成,foreach 循环自动迭代数组的每个元素,当每个元素都被迭代一次后,foreach 循环自动结束;

6.3.2 退出循环

可以使用return结束循环(本质上是终止函数的执行或退出类的方法并将控制权返回给方法的拥有者),JAVA中提供break专门用于强制退出循环;

我们下面介绍break的特殊用途 —— 退出深层循环,要知道在C/C++中要退出多层循环是没有简单方法的,JAVA提供了一种带标签的break语句,实现goto的功能,可以明确指定从何处重新开始执行

break label;

label 是标识代码块的标签。当执行这种形式的 break 语句时,控制权被传递出指定的代码块。用标签(label)可以指定一个代码块,标签可以是任何合法有效的 Java 标识符,后跟一个冒号。加上标签的代码块可以作为 break 语句的对象,使程序在加标签的块的结尾继续执行;

  1. 被加标签的代码块必须包围 break 语句,但是它不需要直接包围 break 的块。也就是说,可以使用一个加标签的 break 语句来退出一系列的嵌套块,但是不能使用 break 语句将控制权传递到不包含 break 语句的代码块;
  2. 标签语句必须和循环匹配使用,使用时书写在对应的循环语句的上面,标签语句以冒号结束。如果需要中断标签语句对应的循环,可以采用 break 后面跟标签名的方式;
public class GotoDemo {
    public static void main(String[] args) {
        label: for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 8; j++) {
                System.out.println(j);
                if (j % 2 != 0) {
                    break label;
                }
            }
        }
    }
}

7.JAVA数组

数组(array)是一种最简单的复合数据类型,它是有序数据的集合,数组中的每个元素具有相同的数据类型,可以用一个统一的数组名和不同的下标来确定数组中唯一的元素。根据数组的维度,可以将其分为一维数组、二维数组和多维数组等;

数组是一种引用数据类型

7.1 一维数组

//声明一个引用该数组的变量,并指明整个变量可以引用的数组类型
type[] arrayName;    // 数据类型[] 数组名,这种方式是推荐的,type[]是一种新的引用类型;
//或者
type arrayName[];    // 数据类型 数组名[],尽管C++是这种声明方式,但之后的语言都逐渐摒弃了这种方法;

声明数组时不要规定数组的长度,会导致错误

int[] score;    // 存储学生的成绩,类型为整型
double[] price;    // 存储商品的价格,类型为浮点型
String[] name;    // 存储商品名称,类型为字符串型

声明了数组,只是得到了一个存放数组的变量,并没有为数组元素分配内存空间,不能使用。因此要为数组分配内存空间,这样数组的每一个元素才有一个空间进行存储, Java 中可以使用 new 关键字来给数组分配空间;

arrayName = new type[size];    // 数组名 = new 数据类型[数组长度];
//当然也可以将分配空间和声明数组的时机放在一起
score = new int[10];
price = new double[30];
name = new String[20];

注意:一旦声明了数组的大小,就不能再修改。这里的数组长度也是必需的,不能少;

8.JAVA集合类

(JAVA的集合类真的是一个非常非常天坑的知识点,光看知识点真的没法理解)

数组长度不可变、数组无法保存具有映射关系的数据,为了保存数量不确定的数据,以及保存具有映射关系的数据(也被称为关联数组),JAVA提供了集合类;

数组元素可以是基本类型的值也可以是对象,而集合类中只能保存对象;

8.1 List集合

8.1.1 ArrayList类

ArrayList 类实现了可变数组的大小,存储在内的数据称为元素;

它还提供了快速基于索引访问元素的方式,对尾部成员的增加和删除支持较好;

使用 ArrayList 创建的集合,允许对集合中的元素进行快速的随机访问,不过,向 ArrayList 中插入与删除元素的速度相对较慢

8.1.2 LinkedList类

LinkedList 类采用链表结构保存对象,这种结构的优点是便于向集合中插入或者删除元素;

需要频繁向集合中插入和删除元素时,使用 LinkedList 类比 ArrayList 类效果高,但是 LinkedList 类随机访问元素的速度则相对较慢(这里的随机访问是指检索集合中特定索引位置的元素);

8.2 set集合

8.2.1 HashSet类

HashSet 是 Set 接口的典型实现,大多数时候使用 Set 集合时就是使用这个实现类。HashSet 是按照 Hash 算法来存储集合中的元素。因此具有很好的存取和查找性能。

8.3 Map集合

Map 是一种键-值对(key-value)集合,Map 集合中的每一个元素都包含一个键(key)对象和一个值(value)对象。用于保存具有映射关系的数据;

Map 接口主要有两个实现类:HashMap 类TreeMap 类。其中,HashMap 类按哈希算法来存取键对象,而 TreeMap 类可以对键对象进行排序;

三、JAVA进阶

1.JAVA类和对象

首先,C++中没有这种将基本数据类型设计为包装类的说法,为什么?因为C++的特性并不仅限于面向对象,所以无论是基本数据类型还是复合数据类型(数组、类类型、结构)有各自的特点和作用;

但是,JAVA不一样,它规定了“一切皆为对象”,它是完全面向对象的语言,也就是说无论是基本数据类型还是其他的类型,所有的操作都要求用对象的形式进行描述(比如.运算符访问属性),然而基本数据类型本身不符合这个规定,所以就出现了包装类这个说法(将在后面简单介绍这一性质,这个性质算不上JAVA的重点);

类之间的关系有:

1.1 对象和对象变量

JAVA中使用构造器来构造一个对象,我们假设使用JAVA中的Date类

new Date();//构造器的名字和类名相同,在构造器前面加上new操作符
Date deadline;

一个对象变量并没有实际包含一个对象(所以在没有初始化对象变量的时候不能对对象变量使用成员运算符等),对象变量仅仅引用一个对象;

可以将JAVA的对象变量看作是C++的对象指针

Date birthday;//JAVA
Date * birthday;//C++

除了显式创建对象以外还可以隐式创建对象,无论釆用哪种方式创建对象,Java 虚拟机在创建一个对象时都包含以下步骤:

1.2 用户自定义类

要创建一个完整的程序,应该将若干类组合在一起,其中只有一个类有main方法;

java Employee*.java
java EmployeeTest.java

1.2.1 定义类

在 Java 中定义一个类,需要使用 class 关键字、一个自定义的类名和一对表示程序体的大括号

[public][abstract|final]class<class_name>[extends<class_name>][implements<interface_name>] {
...
}

中括号“[]”中的部分表示可以省略,竖线“|”表示“或关系”,“|”两边的关键字不能同时出现

1.2.2 构造器

这里所说的构造器本质上就是C++中的构造函数

public Employee(String n, double s, int year, int month, int day)
{
name=n; 
salary=s;
GregorianCalendar calendar = new Gregoriancalendar(year, month -1, day); 
hireDay =calendar. getTime();
}

构造器与类同名,构造器的作用是将实例域初始化为所希望的状态;

构造器与其他方法不同的地方在于构造器总是随着new运算符的执行被调用,不能对一个已经存在的对象调用其构造器来重置实例域;

JAVA因为有自动回收机制所以不支持析构器(为什么这里又说有析构方法呢?Java析构方法 (biancheng.net)解答参考java中怎么没有析构函数?_百度知道 (baidu.com));

仅当类没有提供任何构造器的时候系统才会自动提供一个默认构造器,此时构造对象可以不提供任何构造参数,否则要想使用这种形式只能自己额外提供一个重载构造函数;

构造方法不能被 static、final、synchronized、abstract 和 native(类似于 abstract)修饰

1.2.3 成员变量

声明成员变量格式

public class Test {
[public|protected|private][static][final]<type><variable_name>
}

举例

public class Student {
    public String name;    // 姓名
    final int sex = 0;    // 性别:0表示女孩,1表示男孩
    private int age;    // 年龄
}

1.2.4 成员方法

一个完整的方法通常包括方法名称、方法主体、方法参数和方法返回值类型

声明成员方法的格式

public class Test {
    [public|private|protected][static]<void|return_type><method_name>([paramList]) {
        // 方法体
    }
}

1.3 访问修饰符

JAVA提供了多个作用域修饰符,这些修饰符有类修饰符、变量修饰符和方法修饰符,详细信息可参考Java访问控制修饰符详解(public、 private、protected 和 friendly) (biancheng.net);

类的访问控制符只能是null或者public,方法和属性的访问控制符有 4 个,分别是 public、 private、protected 和 friendly,其中 friendly 是一种没有定义专门的访问控制符的默认情况;

JAVA

1.4 静态域和静态方法

静态成员不依赖于类的特定实例,被类的所有实例共享,就是说 static 修饰的方法或者变量不需要依赖于对象来进行访问,只要这个类被加载,JAVA 虚拟机就可以根据类名找到它们

调用静态成员的语法形式如下:

类名.静态成员

1.4.1 静态域

如果将类的实例域定义为static(每个类中只会有一个这样的域),那么这个类的每一个对象将共享这个静态域,即使没有任何一个类对象,静态域也存在(因为它属于类而不属于任何独立的对象);

实际上JAVA中的静态域一般都被称为类域;

1.4.2 静态常量

静态变量使用较少而静态常量(不属于静态域的字符)使用较多;

可以直接通过类名.常量名的形式获取这个常量;

1.4.3 静态方法

使用静态方法的情况:

静态方法是一种不能向对象实施操作的方法,可以认为静态方法是没有this隐式参数的方法;

因为静态方法不能操作对象故静态方法也就不能访问实例域,但是静态方法可以访问自身类中的静态域;

同样可以通过类名来调用这个方法(当然使用对象名来调用静态方法也没有问题,但本质上静态方法的结果和对象没有任何关系,这容易造成混淆);

1.5 包

JAVA使用包将类组织起来,标准的JAVA类库分布在多个包中;

标准的JAVA包都有一个层次结构,JAVA包名是绝对唯一的;

使用包的其中一个原因是为了确保类名的唯一性(这个包实际上非常类似于C++的名称空间),假如两个程序员都建立了Employee类,只要将这两个类放在不同的包中就不会产生冲突;

1.5.1 类的导入(类导出包)

一个类可以访问所属包中的所有类以及其他包中的公有类public;

访问其他包中的公有类主要有两种方法:

java.util.Date today = new java.util.Date()
import java.util.*;//导入java.util包中的所有类
import java.util.Date;//导入包中一个特定的类

可以使用import语句导入一个特定的类或者整个包,import语句需要位于源文件的顶部、package语句后面

1.5.2 静态导入

import语句不仅可以导入类,还可以导入静态方法和静态域,静态导入使用相对较少,主要用于以下情况:

1.5.3 包导入类

若需要将一个类放入包中,则必须将这个包的名字放在源文件的开头定义类的代码之前

package java.util
public class Employee
{
    ...
    ...
}

如果没有在源文件中防止package语句则这个源文件的类就被放置在一个默认的包中(默认包是一个没有名字的包);

我们需要将包中的文件存放在与完整包名匹配的子目录中,com.horstman.corejava包中的所有源文件都应该被放在对应子目录下,这样编译器也会相应的将类文件放在同样的目录结构中;

JAVA

1.5.4 包作用域

前面介绍的访问修饰符public标记的部分可以被任意的类使用,private标记的部分只能被定义它们的类使用,如果没有指定public和private则这个部分可以被同一个包中的所有方法访问;

1.6 方法参数

程序设计语言中将参数传递给方法/函数有两种方式:

JAVA程序只能采用值调用(无论参数是值还是对象),因此JAVA的方法不能修改传递给它的任何一个参数;

1.7 this关键字

this 关键字可用于任何实例方法内指向当前对象,也可指向对其调用当前方法的对象,或者在需要当前类型对象引用时使用

1.7.1 this.属性名

大部分时候,普通方法访问其他方法、成员变量时无须使用 this 前缀,但如果方法里有个局部变量和成员变量同名,但程序又需要在该方法里访问这个被覆盖的成员变量,则必须使用 this 前缀;

public class Teacher {
    private String name;    // 教师名称
    private double salary;    // 工资
    private int age;    // 年龄
    // 创建构造方法,为上面的3个属性赋初始值
	public Teacher(String name,double salary,int age) {
    	this.name = name;    // 设置教师名称
    	this.salary = salary;    // 设置教师工资
    	this.age = age;    // 设置教师年龄
	}
}

当一个类的属性(成员变量)名与访问该属性的方法参数名相同时,则需要使用 this 关键字来访问类中的属性,以区分类的属性和方法中的参数

1.7.2 this.方法名

this 关键字最大的作用就是让类中一个方法,访问该类里的另一个方法或实例变量(关于实例变量上面已经介绍过this.属性名);

public class Dog {
    // 定义一个jump()方法
    public void jump() {
        System.out.println("正在执行jump方法");
    }
	// 定义一个run()方法,run()方法需要借助jump()方法
	public void run() {
    	// 使用this引用调用run()方法的对象
    	this.jump();
    	System.out.println("正在执行run方法");
	}
}

对于 static 修饰的方法而言,可以使用类来直接调用该方法,如果在 static 修饰的方法中使用 this 关键字,则这个关键字就无法指向合适的对象。所以,static 修饰的方法中不能使用 this 引用。并且 Java 语法规定,静态成员不能直接访问非静态成员;

2.JAVA继承

面向对象除了类和对象以外,另一个基本概念是继承,利用继承可以基于一个已经存在的类来构造一个新类;

继承已经存在的类就是复用这些类的方法和域,再次基础上可以添加一些新的方法和域;

2.1 类的继承

先展示一下由继承Employee类来定义Manager类的格式,extends关键字表示继承

class Manager extends Employee
{
    //添加方法和域
}
super.getSalary();

方法重载:同一个类中包含了两个或两个以上方法名相同的方法,但形参列表不同;

方法重写:也称为覆盖,子类中如果创建了一个与父类中相同名称、相同返回值类型、相同参数列表的方法,只是方法体中的实现不同,以实现不同于父类的功能;

2.2 继承层次

由一个超类派生出的所有类的集合被称为继承层次,在继承层次中从某个特定的类到其祖先的路径被称为继承链

JAVA

2.3 阻止继承

当需要阻止利用某个类来自定义子类,可以在定义该类的时候加上final标识符表明该类是final类

final class Executive extends Manager{
    //阻止人们自定义Executive类的子类
}

类中的方法也可以被final修饰,这样子类就不能覆盖这个方法(final类的所有方法自动称为final方法)

class Employee
{
    public final String getName()
    {
        return name;
    }
}

当然域也可以被声明为final,final域在构造对象之后就不允许改变它们的值了;

将类或方法声明为final的原因是为了确保它们不会在子类中改变语义

2.4 抽象类

从继承结构来看,位于上层的类更加通用、抽象,而位于上层的类具备的一些通用方法,在本层可能暂时无法实现(因为可能需要的某些参数暂时还没有),此时可以使用abstract关键字,这样就完全无需在上层实现该方法(C++中利用纯虚函数实现抽象类);

包含一个或多个抽象方法的类本身必须被声明为抽象的,除了抽象方法外,抽象类还可以包含具体的数据和方法;

abstract class Person
{
    public abstract String getDescription();
    public String getName()
    {
        return name;
    }
    private String name;
}

抽象方法充当着占位的角色,它们的具体实现在子类中,扩展抽象类可以有两种选择:

实际上抽象类就算不包含任何的抽象方法也可以被标记为抽象类,抽象类不能被实例化也就是不能创建这个类的对象;

2.5 Object超类

尽管Object类是所有JAVA类的祖先(C++中没有根类),但是在类声明时没必要这样写

class Employee extends Object

在实际使用中,如果没有明确指出超类,则Object类默认成为该类的超类;

Object obj = new Employee();

Object类中有一些重要的方法,比如equals方法检测两个对象是否相等、toString方法返回表示对象值的字符串,这些Object提供的服务需要掌握:

JAVA

3.包装类

参考自:Java内置的包装类 (biancheng.net)

有时,需要将int这样的基本类型转换为对象,所有的基本类型都有一个与之对应的类。例如,Integer类对应基本类型int。通常,这些类称为包装器(wrapper)、包装类、包装器类。这些对象包装器类拥有很鲜明的名字:Integer,Long,Float,Double,Short,Byte,Character,Void和Boolean(前6个类派生于公共的超类Number)。

3.1 装箱和拆箱

Integer n = 3;
#编译器自动插入一条拆对象包指令
n++;#接着进行int自增计算
#最后将结果打包进对象包Integer内
#将一个Integer对象赋值给一个int值时,会自动拆包
int n = list.get(i);
#上述语句被编译器自动翻译为
int n = list.get(i).intValue();

打包和拆包是编译器认可的,而不是虚拟机;编译器在进行打包和拆包的时候会插入必要的方法调用,接着生成类的字节码

要实现手动装箱和拆箱需要借助包装类的构造方法装箱,通过包装类的intValue方法拆箱

int m = 500;
Integer obj = new Integer(m);  // 手动装箱
int n = obj.intValue();  // 手动拆箱

3.2 Integer类

Integer 类在对象中包装了一个基本类型 int 的值,该类提供了多个方法,能在 int 类型和 String 类型之间互相转换,还提供了处理 int 类型时非常有用的其他一些常量和方法;

Integer 类中的构造方法有以下两个(手动装箱):

Integer integer1 = new Integer(100);    // 以 int 型变量作为参数创建 Integer 对象
Integer integer2 = new Integer("100");    // 以 String 型变量作为参数创建 Integer 对象

可以借助Integer中的方法将字符串(应当只包含数值类型的字符)和int类型的数值相互转换

String str = "456";
int num = Integer.parseInt(str);    // 将字符串转换为int类型的数值
int i = 789;
String s = Integer.toString(i);    // 将int类型的数值转换为字符串

Integer类包含以下四个常量

int max_value = Integer.MAX_VALUE;    // 获取 int 类型可取的最大值
int min_value = Integer.MIN_VALUE;    // 获取 int 类型可取的最小值
int size = Integer.SIZE;    // 获取 int 类型的二进制位
Class c = Integer.TYPE;    // 获取基本类型 int 的 Class 实例

3.3 Float类

Float 类在对象中包装了一个基本类型 float 的值,该类提供了多个方法,能在 float 类型与 String 类型之间互相转换,同时还提供了处理 float 类型时比较常用的常量和方法;

Float 类中的构造方法有以下 3 个。

Float float1 = new Float(3.14145);    // 以 double 类型的变量作为参数创建 Float 对象
Float float2 = new Float(6.5);    // 以 float 类型的变量作为参数创建 Float 对象
Float float3 = new Float("3.1415");    // 以 String 类型的变量作为参数创建 Float 对象

可以借助Integer中的方法将字符串(应当只包含数值类型的字符)和float类型的数值相互转换

String str = "456.7";
float num = Float.parseFloat(str);    // 将字符串转换为 float 类型的数值
float f = 123.4f;
String s = Float.toString(f);    // 将 float 类型的数值转换为字符串

Float类包含很多常量,具体可以查阅资料

float max_value = Float.MAX_VALUE;    // 获取 float 类型可取的最大值
float min_value = Float.MIN_VALUE;    // 获取 float 类型可取的最小值
float min_normal = Float.MIN_NORMAL;    // 获取 float 类型可取的最小标准值
float size = Float.SIZE;    // 获取 float 类型的二进制位

3.4 Number超类

上面说过有六个基本的包装类派生于公共的Number超类,Number同时也是一个抽象类,Number类属于java.lang包;

因为抽象类不能被实例化,只能实例化它的具体的子类(Double、Float...),下面简单展示一下Number类的使用

Number num = new Double(12.5);#定义一个抽象类的对象变量,只能引用非抽象子类的对象
System.out.println("返回 double 类型的值:" + num.doubleValue());#返回 double 类型的值:12.5
System.out.println("返回 int 类型的值:" + num.intValue());#返回 int 类型的值:12
System.out.println("返回 float 类型的值:" + num.floatValue());#返回 float 类型的值:12.5

4.System类

System 类位于 java.lang 包,代表当前JAVA程序的运行平台,系统级的很多属性和控制方法都放置在该类的内部。由于该类的构造方法是 private 的,所以无法创建该类的对象,也就是无法实例化该类;

System 类提供了一些类变量和类方法,允许直接通过 System 类来调用这些类变量和类方法;

4.1 成员变量

System类有3个静态成员变量:

#编写一行输出数据的典型方式
System.out.println(data);
#println 方法是属于流类 PrintStream 的方法,而不是 System 中的方法

4.2 成员方法

System 类中提供了一些系统级的操作方法,常用的方法有 arraycopy()、currentTimeMillis()、exit()、gc() 和 getProperty(),具体使用方法可以查阅资料;

5.反射

JAVA反射机制是指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性(简单来说,反射机制指的是程序在运行时能够获取自身的信息);

Java 反射机制主要提供了以下功能,这些功能都位于java.lang.reflect包:

JAVA中反射机制用的比较少,这里就不再赘述,感兴趣可以自己查阅资料;