本篇博客是Java学习笔记,因为以前只接触过C和C++以及python,对于Java只是略知一点,所以在此对自己学习Java的成果做一些记录。下来大部分内容会以C++和python作为对照来学习Java,因为暂时还是Java小白,所以难免有些疏漏,若有错误还请各位看官指正。
文章目录
一、Java基本了解
Java是一门开源、免费、纯面向对象且跨平台的语言,与C和C++不同。
1、Java的特性
(1)简单性:相对于C++而言,Java没有多继承,屏蔽了指针的概念,所以相对简单,毕竟对于C和C++程序员来说,指针造成的内存管理确实是一大问题,但Java的底层是用C++写的。
(2)面向对象:Java是一门纯面向对象的语言,在Java中任何事物都会被抽象成类,而C++虽说也是面向对象编程,但依旧会有全局函数这样的东西,而Java中则没有。
(3)可移植性:Java程序由于运行机制和C++不同,C++由于直接使用底层系统API,linux和windows上的系统调用可以被直接使用,这也导致C++程序没有移植性。而Java程序是运行在JVM上的,和底层系统的交互是由JVM完成,程序编写人员并不需要在意这些。
(4)多线程
(5)健壮性:Java包含自动垃圾回收机制(GC:garbage collection),所以Java并不需要像C中使用malloc申请空间,还需要使用free释放内存,也不用像C++中new然后配套delete。
(6)安全性。
2、程序的加载和执行
和C/C++程序需要进行预编译、编译、汇编、链接四个阶段不同,Java程序只经过编译阶段即可运行。
(1)编译阶段
.java文件经过语法检查生成对应的.class文件,称作字节码文件,Java提供了javac命令来进行程序的编译,例如我们要编译一个名为Master的java源文件,则需要在命令行中输入:
javac Master.java
此处笔者在学习时遇到一个错误,就是当代码中夹杂中文注释时使用上述命令会报很多错,类似于下面这种:
这是由于字符编码的问题导致的,此时只需要加上设置字符编码的选项即可(使用IDE不会出现这种问题)
javac -encoding utf-8 Master.java
注意当一个Java源文件中包含多个类时则会生成多个class文件。生成的class文件则可以直接拷贝到其他操作系统上运行,这也体现了Java的可移植性。
(2)运行阶段
在编译成功后对应的class文件生成,
运行的命令为
java Master
注意此处只需要运行对应的类名即可,不需要加上.class后缀。在我们输入该命令后,系统会启动Java虚拟机,JVM会启动类加载器ClassLoader,然后ClassLoader会在硬盘上搜索对应的.class文件,再将该字节码文件装载到JVM中,JVM会将.class文件解释成二进制码,然后由JVM完成二进制码和底层硬件的交互。但解释字节码会比解释二进制码慢得多,而JVM有相应选项可以将使用最多的字节码序列直接翻译成机器码,称作即时编译。
3、其余一些简单的命令
(1)native2ascii:将输入的文字转换成对应的unicode编码
(2)javadoc:java中的注释方法分为三种,前两种和C中的一样://和/**/,还有一种注释称为javadoc注释,格式如下:
/**
*注释内容
*/
这是一种较专业的注释,当Java源文件中包含这种注释时,我们使用javadoc命令可以对源文件中的这种注释进行提取,进而生成对应的帮助文档。
4、语法
Java的语法基本和C/C++相同,不过由于Java是纯面向对象的语言,所以还是有一些不同,比如不能实现全局方法,不能在类体外和类体内方法外直接书写Java语句,但是可以声明变量,同样的一个逻辑,在C++中是一种实现,但Java中又是另一种实现:
//C++实现一个Test类,包含a和b两个私有成员变量,在主函数中声明一个栈上的对象。
#include<iostream>
using namespace std;
class Test{
public:
Test(){}
private:
int a;
int b;
}
int main(){
Test test=Test();
return 0;
}
//Java实现一个Test类,该类包含程序入口,私有变量为a和b,并在堆上new一个对象
public class Test{
public static void main(String[] args){
Test test=new Test();
}
private int a;
private int b;
public Test(){}
}
以上两段代码实现了相同的功能,但明显实现不同,具体后面在类和对象部分再细说,Java的语法要注意以下几点:
(1)一个Java源文件中可以定义多个class
(2)一个Java源文件当中的public的class不是必须的
(3)每一个class都会对应生成一个.class字节码文件
(4)一个Java源文件当中如果定义public的class的话,则只能有一个public的class,且该类名称必须和Java源文件的名称相同。
(5)每一个class中都可以编写main方法,想执行该类的main方法则使用相应命令运行即可。
二、语言基础
1、标识符
Java中的标识符包括:类名、方法名、变量名、接口名、常量名,其命名规则为:只能以数字、字母、下划线以及美元符号$组成,不可以数字开头,且Java是大小写敏感的语言,同其他语言一样不可以关键字作为标识符。其命名规范也遵守驼峰命名法:类名接口名首字母大写,后面每个单词的首字母大写;变量名首字母小写,后面每个单词的首字母大写;常量名全部大写。
2、变量
Java根据变量声明的位置进行分类:方法体内声明的变量称作局部变量,方法体外类内声明的变量称作实例变量,当实例变量声明但未初始化时系统会赋予默认值。
3、数据类型
Java的数据类型分为两大类,分别是基本数据类型和引用数据类型,引用数据类型在我看来和C++中的指针是一样的,都是存储堆上数据的地址,只是没有显式的写出“*”而已。
(1)基本数据类型
数据类型 | 占用字节数/系统赋予的默认值 |
---|---|
byte | 1字节/0 |
short | 2字节/0 |
int | 4字节/0 |
long | 8字节/0 |
float | 4字节/0.0 |
double | 8字节/0.0 |
char | 2字节/\u0000 |
boolean | 1字节中的一个bit位/false |
Java中不可以使用0和1表示false与true,这点与C/C++不同。且Java中的char型占用两个字节,新增了byte型。
(2)引用数据类型
引用数据类型就是我们自己根据基础数据类型扩展的数据类型,比如类、接口等。
4、数据类型之间的相互转换
(1)Java中的整型字面值会被默认当做int型处理,所以当一个整型字面值被赋给long型时需要给该数字后加上L,表示该数字为long型再赋值。
(2)当大容量类型转成小容量类型时需要手动进行强制类型转换,比如将int型变量a转成short型,则需要使用如下语句:
short b=(int)a;
编译时不会出现错误,但在运行时可能会损失精度。
(3)Java中的浮点数会默认为double类型,当需要使其为float类型时需要在数字后面加上f/F,否则会报错。
(4)对于财务软件使用float和double也是精度不足的,Java提供了BigDecimal.class用以处理高精度数字。
(5)当byte、short、char做混合运算的时候,会自动转成int型来计算。
5、运算符
基本运算符和C++的差不多,在这里只记录逻辑运算符:
运算符 | 含义 |
---|---|
& | 逻辑与:用以判断两个条件是否同为真 |
| | 逻辑或:用以判断条件是否有一个为真 |
! | 逻辑非:对判断条件取反 |
^ | 逻辑异或:两个算子的bool值不同则为真 |
&& | 短路与:功能与逻辑与相同,但若第一个算子为假则不继续判断 |
|| | 短路或:功能与逻辑或相同,但若第一个算子为真则不继续判断 |
因为在C++中没有短路与和短路或的概念,所以在此需要记录一下,C++中的&、|、!等都是用于操作位运算的,只有&&和||是用于逻辑判断。而Java中的&、|、!也可以用于逻辑判断,它们和短路与以及短路或的区别在于它们不偷懒,也就是说两个算子都会进行判断,不会提前结束。
6、程序控制语句
大体上和C++相同
控制语句 | 与C++的差别 |
---|---|
if语句 | 完全相同 |
switch语句 | case中的元素可以为String类型 |
while | 相同 |
dowhile | 相同 |
for | 相同 |
break | 相同 |
continue | 相同 |
注意在C++中,switch语句中的case只可以为char和数字,但Java中的case可以为String类型,也就是说可以出现如下的情况:
switch(a){
case "abc":
doSome();
break;
case "bcd":
doSome2();
break;
default:
doSome3();
}
7、方法(method)
Java中所说的方法其实就是C++中的函数,但由于Java是纯面向对象的语言,所以在方法定义上有些差别,但也遵循一些规则,比如Java中不能存在全局方法,方法体内不能再定义方法这些基本原则。
(1)方法的定义格式
[修饰符列表] [返回值] [方法名](形参列表){
方法体;
}
(2)方法体执行过程中JVM的内存分配
a.方法区:用于存储方法代码片段,方法代码片段属于.class字节码文件的一部分,字节码文件在类加载的时候存入到当前区中。所以该内存最先有数据。
b.堆区:存储new出来的数据。
c.栈区:方法的栈内存开辟,局部变量的存储等。
(3)方法重载
方法重载和C++中是相同的,生成符号的规则是方法名加形参列表,所以同名不同参即可重载。
下一篇博客记录类和对象以及继承和多态。