Java语言基础

Java语言基础语法和编程入门

Java 后端 第一节课:语言基础

学长 g 语

  • 0基础小白不建议阅读书籍,看视频更好入手,Java 有其他语言梦寐以求的学习资源,在我们学习java后端的很长一段时间内,我们的学习途径都可以是bilibili

  • 最重要的就是多敲代码,多敲代码,多敲代码。不要图快,跟着视频学习一定要自己敲一遍代码

  • 养成记电子档笔记的习惯,可以学习markdown语法,用Typora来记笔记很方便,b站有Typora破解方法

学 JavaSE 前先了解这门语言的主要特性:

  • Java 语言是简单的:

    Java 语言的语法与 C 语言和 C++ 语言很接近,使得大多数程序员很容易学习和使用。另一方面,Java 丢弃了 C++ 中很少使用的、很难理解的、令人迷惑的那些特性,如操作符重载、多继承、自动的强制类型转换。特别地,Java 语言不使用指针,而是引用。并提供了自动分配和回收内存空间,使得程序员不必为内存管理而担忧。

  • Java 语言是面向对象的:

    Java 语言提供类、接口和继承等面向对象的特性,为了简单起见,只支持类之间的单继承,但支持接口之间的多继承,并支持类与接口之间的实现机制(关键字为 implements)。Java 语言全面支持动态绑定,而 C++语言只对虚函数使用动态绑定。总之,Java语言是一个纯的面向对象程序设计语言。

  • Java 是高性能的:

    与那些解释型的高级脚本语言相比,Java 的确是高性能的。事实上,Java 的运行速度随着 JIT(Just-In-Time)编译器技术的发展越来越接近于 C++。

  • Java具有完整并不断发展的生态

    Java发展时间长,受到全世界众多程序员的青睐,建立了完整的生态。你在编写Java程序时遇见的bug永远有人比你先遇见,所以你可以相关网站上寻找解答。Java还有强大的spring框架,在不久的学习后你们也会接触到

我们再来接触几个概念:

  • JDK(Java Development Kit):JDK包含了JRE.简单的说JDK是面向开发人员使用的SDK,它提供了Java的开发环境和运行环境。
  • JRE(Java Runtime Environment):包含了JVM,java基础类库。是使用java语言编写的程序运行所需要的软件环境,是提供给想运行java程序的用户使用的。
  • JVM(Java Virtual Machine):JVM是编译java代码的虚构计算机,jvm使得Java语言在不同平台上运行时不需要重新编译。
  • Java SE(Standard Edition):Java SE 是 Java 的标准版,提供了 Java 编程语言的核心功能和库。
  • Java EE(Enterprise Edition):Java EE 是 Java 的企业版,扩展了 Java SE,提供了用于开发企业级应用程序的功能。
  • Java ME(Micro Edition):Java ME 是 Java 的微型版,专为嵌入式设备和移动设备设计。

接下来我们进入Java编程:

少不了的就是“问世程序”:

1
2
3
4
5
6
public class HelloWorld {
public static void main(String[] args) {
    //输出hello,world!
    System.out.println("hello,world!");
}
}

​ 编写完代码,按下IDEA快捷键ctrl + shift + f10 或者右键点击运行就能输出hello,world了

Java基本数据类型:

Java中分为两大数据类型

  • 基本数据类型
  • 引用数据类型

基本数据类型

//Java内置了八种基本数据类型

//摘自《java编程思想》

  • 这些常用的类型作为基本类型,与其他类型区分开
  • 对于这些基本类型,java采用与Cpp相同的方法,不用new来创建变量,而是创建一个并非是引用的“自动”变量
  • 这个变量直接存储值,并置于栈中,因此更高效
  • 这些基本类型的所占存储空间不会随机器硬件架构而变化,java具有可移植性
  • 每个基本类型都对应一个包装类型,可在堆中创建一个非基本对象,用来表示对应的基本类型
  • 自动包装和反向转换:
Character ch = 'x';` `char c = ch;
  • 高精度数字:
    • java提供了BigInteger(存整数)和BigDecimal(存小数)、
    • 方法调用 取代 运算符,速度换精度
整数
数据类型说明
byte占用一个字节
short占用两个字节
int占用四个字节
long占用八个字节
浮点类
数据类型说明
float4字节, 没有后缀F的浮点数值(如3.14)默认为double类型,当然,也可以在浮点数值后面添加后缀D或的(例如,3.14D)。
double8字节,double表示这种类型的数值精度是float类型的两倍(有人称之为双精度数值)。绝大部分应用程序都采用double类型。在很多情况下,float类型的精度很难满足需求
字符类
数据类型说明
char2字节,16位。char在java中是16位,用于存放单个字符。用单引号【’ ‘】括住,‘A’;表示一个字符,“A"表示一个字符串,即一个字符序列
布尔型
数据类型说明
boolean变量存储为1 个字节,只能是 True 或是 False

类型默认值:

数据类型默认值
byte0
short0
int0
long0L
float0.0f
double0.0d
char‘u0000’
String (or any object)null
booleanfalse

引用数据类型

引用数据类型类似于C的指针,指向一个对象

数组和对象都是引用数据类型

1
2
3
Studio studio =new Studio("cfc");  

Scanner sca=new Scanner(System.in);

java修饰符

Java的修饰符主要分为两种

  • 访问修饰符
  • 非访问修饰符

访问修饰符

Java中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。Java 支持 4 种不同的访问权限。

范围:public > protected > default > private

  • default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
  • private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
  • public : 对所有类可见。使用对象:类、接口、变量、方法
  • protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)

非访问修饰符

static:

1:static是静态意思,可以修饰成员变量和成员方法;static修饰成员变量表示该成员变量在内存中只存储一份,可以被共享访问,修改。

2:static修饰的成员属性,成员方法,不属于任何一个对象,它属于一个类模板公用,我们调用它时,直接使用类名加 “.“就可以直接访问了

//摘自《java编程思想》

  • 声明一个事物是static时,就意味着这个域或方法不会与包含它的那个类的任何实例对象关联起来,所以不用创建这个类的任何对象,我们也能调用其static方法和static域
  • 实例变量(不含static)是与相应的实例对象绑定的,存储在中的实例对象里
  • 静态变量(含static)是与每个类相绑定的,属于是这个类的实例对象共享的,存储在方法区中(类就存储在方法区中)
  • 特点:
    • 随着类的加载而加载
    • 优先于对象存在
    • 被所有对象所共享
    • 可以直接被类名调用(也可以对象的引用调用)
  • 注意:
    • 静态方法只能访问静态成员;实例方法既可以访问静态也可以访问非静态
    • 静态方法中不可以定义this和super关键字,因为静态优于对象存在

final:

final意味着不可变:不可变的是变量的引用而非引用指向对象的内容(String)

1、被final修饰的类不可以被继承

2、被final修饰的方法不可以被重写

3:被final修饰的变量不可以被改变

4:final修饰的变量往往和static搭配

Java 运算符

计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量。我们可以把运算符分成以下几组:

  • 算术运算符
  • 关系运算符
  • 位运算符
  • 逻辑运算符
  • 赋值运算符
  • 其他运算符

算术运算符

算术运算符用在数学表达式中,它们的作用和在数学中的作用一样。下表列出了所有的算术运算符。

表格中的实例假设整数变量A的值为10,变量B的值为20:

操作符描述例子
+加法 - 相加运算符两侧的值A + B 等于 30
-减法 - 左操作数减去右操作数A – B 等于 -10
*乘法 - 相乘操作符两侧的值A * B等于200
/除法 - 左操作数除以右操作数B / A等于2
取余 - 左操作数除以右操作数的余数B%A等于0
++自增: 操作数的值增加1B++ 或 ++B 等于 21(区别详见下文)
自减: 操作数的值减少1B– 或 –B 等于 19(区别详见下文)

关系运算符

运算符描述例子
==检查如果两个操作数的值是否相等,如果相等则条件为真。(A == B)为假。
!=检查如果两个操作数的值是否相等,如果值不相等则条件为真。(A != B) 为真。
>检查左操作数的值是否大于右操作数的值,如果是那么条件为真。(A> B)为假。
<检查左操作数的值是否小于右操作数的值,如果是那么条件为真。(A <B)为真。
>=检查左操作数的值是否大于或等于右操作数的值,如果是那么条件为真。(A> = B)为假。
<=检查左操作数的值是否小于或等于右操作数的值,如果是那么条件为真。(A <= B)为真。

逻辑运算符

下表列出了逻辑运算符的基本运算,假设布尔变量A为真,变量B为假

操作符描述例子
&&称为逻辑与运算符。当且仅当两个操作数都为真,条件才为真。(A && B)为假。
| |称为逻辑或操作符。如果任何两个操作数任何一个为真,条件为真。(A | | B)为真。
!称为逻辑非运算符。用来反转操作数的逻辑状态。如果条件为true,则逻辑非运算符将得到false。!(A && B)为真。

赋值运算符

下面是Java语言支持的赋值运算符:

操作符描述例子
=简单的赋值运算符,将右操作数的值赋给左侧操作数C = A + B将把A + B得到的值赋给C
+ =加和赋值操作符,它把左操作数和右操作数相加赋值给左操作数C + = A等价于C = C + A
- =减和赋值操作符,它把左操作数和右操作数相减赋值给左操作数C - = A等价于C = C - A
* =乘和赋值操作符,它把左操作数和右操作数相乘赋值给左操作数C * = A等价于C = C * A
/ =除和赋值操作符,它把左操作数和右操作数相除赋值给左操作数C / = A,C 与 A 同类型时等价于 C = C / A

自增自减运算符

自增自减运算符是对单个数进行加一减一的操作

// 自增运算符分为前缀自增++a,和后缀自增a++
// 前缀自增就是先进行自增运算,再进行表达式运算。后缀自增则相反
// 同样自减运算也有前缀自减--a,和后缀自减a--。
int a = 1;
int b = 1;
int c = 1;
int d = 1;
System.out.println(++a); // 2
System.out.println(b++); // 1
System.out.println(--c); // 0
System.out.println(d--); // 1

控制流程语句

条件语句:if-else

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
if(condition){
// do something
statement
}else if(condition){
// do something  
statement
}else{
// do something  
statement
}

迭代/循环语句:while,do-while,for

while:

1
2
3
4
// condition为true的时候执行statement
while(condition){
statement
}

do-while:

1
2
3
do {
statement
} while (condition)

for:

1
2
3
4
5
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
System.out.println("1累加到100的结果是:" + sum);

中断:return、continue、break

return:

return 关键字用于从方法中返回一个值或终止方法的执行

continue:

1
2
3
4
5
6
7
8
int sum = 0;
for (int i = 1; i <= 100; i++) {
if (i % 2 == 0) {
    continue;
}
sum += i;
}
System.out.println("1到100之间的奇数和为:" + sum);

continue的作用就是跳过本次循环的执行,直接跳转到i++,然后判断i<=100,再次进入循环体;

break:

1
2
3
4
5
6
7
8
9
int sum = 0;
int i;
for (i = 1; i <= 100; i++) {
if (i == 77) {
    break;
}
sum += i;
}
System.out.println("1累计到76的结果:" + sum + "  i:" + i);

执行break后,就直接退出for循环执行打印语句了. i为77的时候,执行了break,此时i++并没有执行.

多重选择语句:switch

当选择的条件变多时,if-else if的方式会大大降低可读性.使用switch语句可以让结构变得清晰一点.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Scanner in = new Scanner(System.in);
System.out.println("请输入当前月份");
int month = in.nextInt();
switch (month){
case 1 :
    System.out.println("一月");break;
case 2 :
    System.out.println("二月");break;
case 3 :
    System.out.println("三月");break;
case 4 :
    System.out.println("四月");break;
case 5 :
    System.out.println("五月");break;
case 6 :
    System.out.println("六月");break;
case 7 :
    System.out.println("七月");break;
case 8 :
    System.out.println("八月");break;
case 9 :
    System.out.println("九月");break;
case 10 :
    System.out.println("十月");break;
case 11 :
    System.out.println("十一月");break;
case 12 :
    System.out.println("十二月");break;
default:
    System.out.println("错误的输入");break;
}

这里我们用switch来匹配输入的月份,case则是符合某个数会触发的操作,break则表示跳出整个switch,当无法匹配到case的值时,会进入到default中.

数组

数组是存储数据的容器,长度固定,并且其中的元素数据类型需要保持一致

数组初始化

数组初始化分为静态初始化和动态初始化

// 数组存储的数据类型[ ] 数组名字 = new 数组存储的数据类型[数组长度];
    // 数组存储的数据类型 数组名字[ ] = new 数组存储的数据类型[数组长度];
    
    // 动态初始化,初始化时就指定长度
    int[] arr = new int[3];
    // 静态初始化,初始化时指定内容
    int[] arr2 = new int[]{1,3,5,7};
    // 各种数据类型都可以有数组,例如下面就是一个String的数组
    String[] sectionArr = {"前端","后端Java","后端Go","产品及运营","UI","运维"};

二维数组

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// 定义一个二维数组
int[][] array;

// 创建一个二维数组(3行4列)
array = new int[3][4];

int[][] array = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};

最后我们就由外向内挨着分解这个“问世程序”:

1
2
3
4
public class HelloWorld {
   
   
}
  • public(公开的)是访问修饰符中的一种
  • class(类)
  • HelloWorld则是这个类的名字
  • { }:大括号,用来包住代码
1
2
3
public static void main(String[] args) {
     
}
  • static(静态的)
  • void(无)
  • main(主)
  • String [ ] (字符串数组)
  • args则是这个数组的名字
1
2
//输出hello,world!
System.out.println("hello,world!");
  • // 是一种java注释方法,可以更容易的看懂你的代码。
  • System 是JDK的内置类,ctrl 加鼠标左键(看源码)点击System,可以进入看到这个类的全貌
  • Systemjava.lang包里的一个final类,而每个Java程序是默认import java.lang.*的,因此即使程序中没有手动导入,也可访问到System
  • out是System类里的一个不可变的引用变量
  • System类的源码有public static final PrintStream out = null;
  • println()是PrintStream类的一个实例方法
  • “hello,world!“是一段我们想要输出到控制台的字符串

但System.out.println(“hello,world!”);的背后还远不止这么简单,还牵涉了IO和cpp的native方法

课后任务:

1.*基本数据类型和运算符*:

  • 编写一个程序,计算并输出从1加到100的结果。
  • 创建一个程序,使用算术运算符实现两个数的加、减、乘、除运算,并处理除数为零的情况。
  • 编写一个程序,判断一个整数是否为素数。

2.*控制流程语句*:

  • 使用if-else语句编写一个程序,根据用户输入的成绩(0-100),输出相应的等级(A、B、C、D、F)。
  • 利用for循环打印出九九乘法表。
  • 编写一个程序,使用while循环计算并输出100以内所有偶数的和。

3.*数组*:

  • 创建一个程序,初始化一个包含10个整数的数组,并使用for循环打印出数组中的每个元素。
  • 编写一个程序,实现一个二维数组的初始化,并计算其所有元素的总和。
  • 使用Arrays类的sort方法对一个整数数组进行排序,并打印排序后的结果。