Java基础

Mr.Tong...
  • Java
  • Java
大约 22 分钟

一、基础语法

一个Java程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作。下面简要介绍下类、对象、方法和实例变量的概念。

  • 对象:对象是类的一个实例,有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。
  • :类是一个模板,它描述一类对象的行为和状态。
  • 方法:方法就是行为,一个类可以有很多方法。逻辑运算、数据修改以及所有动作都是在方法中完成的。
  • 实例变量:每个对象都有独特的实例变量,对象的状态由这些实例变量的值决定。

1. 基本语法

编写Java程序时,应注意以下几点:

  • 大小写敏感:Java是大小写敏感的,这就意味着标识符Hello与hello是不同的。
  • 类名:对于所有的类来说,类名的首字母应该大写。如果类名由若干单词组成,那么每个单词的首字母应该大写,例如 MyFirstJavaClass 。
  • 方法名:所有的方法名都应该以小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写。
  • 源文件名:源文件名必须和类名相同。当保存文件的时候,你应该使用类名作为文件名保存(切记Java是大小写敏感的),文件名的后缀为.java。(如果文件名和类名不相同则会导致编译错误)。
  • 主方法入口:所有的Java 程序由**public static void main(String\**[]\** args)** 方法开始执行。

2. 标识符

Java所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。

关于Java标识符,有以下几点需要注意:

  • 所有的标识符都应该以字母(A-Z或者a-z),美元符($)、或者下划线(_)开始
  • 首字符之后可以是字母(A-Z 或者 a-z),美元符($)、下划线(_)或数字的任何字符组合
  • 关键字不能用作标识符
  • 标识符是大小写敏感的
  • 合法标识符举例:age、$salary、_value、__1_value
  • 非法标识符举例:123abc、-salary

3. 修饰符

像其他语言一样,Java可以使用修饰符来修饰类中方法和属性。主要有两类修饰符:

  • 访问控制修饰符 : default, public , protected, private
  • 非访问控制修饰符 : final, abstract, staticsynchronizedvolatile

3. 变量

变量就是系统为程序分配的一块内存单元,用来存储各种类型的数据。由于该存储单元中的数据可以发生改变,因此得名为"变量"。

按所属的数据类型划分:

  • 基本数据类型变量

  • 引用数据类型变量

按被声明的位置划分:

  • 局部变量:方法或语句块内部定义的变量

  • 成员变量:方法外部、类的内部定义的变量

成员变量又可以划分为类变量和实例变量,未被static修饰的成员变量也叫实例变量,它存储于对象所在的堆内存中,生命周期与对象相同,被static修饰的成员变量也叫类变量,它存储于方法区中,生命周期与当前类相同。

特别注意:类的外面不能有变量的声明

成员变量与局部变量的区别?

  • 语法形式 :从语法形式上看,成员变量是属于类的,而局部变量是在代码块或方法中定义的变量或是方法的参数;成员变量可以被 public,private,static 等修饰符所修饰,而局部变量不能被访问控制修饰符及 static 所修饰;但是,成员变量和局部变量都能被 final 所修饰。
  • 存储方式 :从变量在内存中的存储方式来看,如果成员变量是使用 static 修饰的,那么这个成员变量是属于类的,如果没有使用 static 修饰,这个成员变量是属于实例的。而对象存在于堆内存,局部变量则存在于栈内存。
  • 生存时间 :从变量在内存中的生存时间上看,成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随着方法的调用而自动生成,随着方法的调用结束而消亡。
  • 默认值 :从变量是否有默认值来看,成员变量如果没有被赋初始值,则会自动以类型的默认值而赋值(一种情况例外:被 final 修饰的成员变量也必须显式地赋值),而局部变量则不会自动赋值。

5. 关键字

Java 中有一些赋予特定的含义,有专门用途的字符串称为关键字(keyword),全部是小写。

分类关键字
访问控制privateprotectedpublic
类,方法和变量修饰符abstractclassextendsfinalimplementsinterfacenative
newstaticstrictfpsynchronizedtransientvolatileenum
程序控制breakcontinuereturndowhileifelse
forinstanceofswitchcasedefaultassert
错误处理trycatchthrowthrowsfinally
包相关importpackage
·基本类型booleanbytechardoublefloatintlong
short
变量引用superthisvoid
保留字gotoconst

标识符和关键字的区别是什么?

在我们编写程序的时候,需要大量地为程序、类、变量、方法等取名字,于是就有了 标识符 。简单来说, 标识符就是一个名字

有一些标识符,Java 语言已经赋予了其特殊的含义,只能用于特定的地方,这些特殊的标识符就是 关键字 。简单来说,关键字是被赋予特殊含义的标识符 。比如,在我们的日常生活中,如果我们想要开一家店,则要给这个店起一个名字,起的这个“名字”就叫标识符。但是我们店的名字不能叫“警察局”,因为“警察局”这个名字已经被赋予了特殊的含义,而“警察局”就是我们日常生活中的关键字。

6. Java注释

类似于C/C++,Java也支持单行以及多行注释。注释中的字符将被Java编译器忽略。

Java 中的注释有三种:

  1. 单行注释//开头,通常用于解释方法内某单行代码的作用。
  2. 多行注释/开头,/结尾,通常用于解释一段代码的作用。
  3. 文档注释 :以/**开头,*/结尾,123通常用于生成 Java 开发文档。

二、数据类型

由于变量记录的数据内容大小不同, 导致所需的存储单元大小不同,在 Java 语言中使用数据类型的概念加以描述。

image-20230717153604189

数据类型大小描述
字节型(byte)1 字节存储从 -128 到 127 的整数
短整数型(short)2 字节存储从 -32,768 到 32,767 的整数
整数型(int)4 字节存储从 -2,147,483,648 到 2,147,483,647 的整数
长整数型(long)8 字节存储从 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 的整数
浮点型(float)4 字节存储小数。 足以存储 6 到 7 个十进制数字
双 精 度 型(double)8 字节存储小数。 足以存储 15 位十进制数字
布尔型(boolean)1 字节存储 true 或 false 值
字符型(char)2 字节存储单个字符/字母或 ASCII 值

字节是计算机信息技术用于计量存储容量的一种计量单位,作为一个单位来处理的一个二进制数字串,是构成信息的一个小单位。Java中的字节是八位的字节,即它包含八位的二进制数。

类型转换

boolean 类型不能转换成任何其它数据类型。

**自动类型转换:**容量小的类型自动转换成容量大的数据类型

byte,short,int -> float ->long ->double

byte,short,int 不会互相转换,它们三者在计算时会转换成 int 类型

**强制类型转换:**容量大的类型转换成容量小的数据类型时,要加上强制转换符

long l = 100L;

int i = (int)l;

有可能造成精度降低或数据溢出,使用时要小心。

三、运算符

1. 算术运算符

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

++: 如果是变量前缀:先对此变量加 1,再执行其他的操作。

如果是变量后缀:先执行当前语句的其他操作,再对此变量加 1

--: 如果是变量前缀:先对此变量减 1,再执行其他的操作。

如果是变量后缀:先执行当前语句的其他操作,再对此变量减 1

2. 关系运算符

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

3. 赋值运算符

操作符描述例子
=简单的赋值运算符,将右操作数的值赋给左侧操作数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
(%)=取模和赋值操作符,它把左操作数和右操作数取模后赋值给左操作数C%= A等价于C = C%A
<< =左移位赋值运算符C << = 2等价于C = C << 2
>> =右移位赋值运算符C >> = 2等价于C = C >> 2
&=按位与赋值运算符C&= 2等价于C = C&2
^ =按位异或赋值操作符C ^ = 2等价于C = C ^ 2
| =按位或赋值操作符C | = 2等价于C = C | 2

4. 逻辑运算符

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

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

5. 位运算符

Java定义了位运算符,应用于整数类型(int),长整型(long),短整型(short),字符型(char),和字节型(byte)等类型。

位运算符作用在所有的位上,并且按位运算。假设a = 60,b = 13;它们的二进制格式表示将如下:

A = 0011 1100
B = 0000 1101
-----------------
A&B = 0000 1100
A | B = 0011 1101
A ^ B = 0011 0001
~A= 1100 0011

下表列出了位运算符的基本运算,假设整数变量 A 的值为 60 和变量 B 的值为 13:

操作符描述例子
如果相对应位都是1,则结果为1,否则为0(A&B),得到12,即0000 1100
|如果相对应位都是 0,则结果为 0,否则为 1(A | B)得到61,即 0011 1101
^如果相对应位值相同,则结果为0,否则为1(A ^ B)得到49,即 0011 0001
按位取反运算符翻转操作数的每一位,即0变成1,1变成0。(〜A)得到-61,即1100 0011
<<按位左移运算符。左操作数按位左移右操作数指定的位数。A << 2得到240,即 1111 0000
>>按位右移运算符。左操作数按位右移右操作数指定的位数。A >> 2得到15即 1111
>>>按位右移补零操作符。左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充。A>>>2得到15即0000 1111
public class Test {
  public static void main(String[] args) {
     int a = 60; /* 60 = 0011 1100 */ 
     int b = 13; /* 13 = 0000 1101 */
     int c = 0;
     c = a & b;       /* 12 = 0000 1100 */
     System.out.println("a & b = " + c );
 
     c = a | b;       /* 61 = 0011 1101 */
     System.out.println("a | b = " + c );
 
     c = a ^ b;       /* 49 = 0011 0001 */
     System.out.println("a ^ b = " + c );
 
     c = ~a;          /*-61 = 1100 0011 */
     System.out.println("~a = " + c );
 
     c = a << 2;     /* 240 = 1111 0000 */
     System.out.println("a << 2 = " + c );
 
     c = a >> 2;     /* 15 = 1111 */
     System.out.println("a >> 2  = " + c );
  
     c = a >>> 2;     /* 15 = 0000 1111 */
     System.out.println("a >>> 2 = " + c );
  }
} 

6. 字符串连接运算符

String s="He" + "llo"; 结果"Hello"

"+"除了可用于字符串相连接,也能将字符串与其它的数据类型相连成一个新的字符串。 如:String s="x" + 123; 结果"x123"

7. 三目运算符

X ? Y : Z

X 为 boolean 类型表达式,先计算 x 的值,若为 true,整个三目运算的结果为表达式 y 的值,否则整个运算结果为表达式 z 的值。

例:

int score = 75;

String type = score >=60 ? "及格" : "不及格";

四、循环结构

顺序结构的程序语句只能被执行一次。

如果您想要同样的操作执行多次,就需要使用循环结构。

Java中有三种主要的循环结构:

  • while 循环
  • do…while 循环
  • for 循环

在 Java5 中引入了一种主要用于数组的增强型 for 循环。

1. while 循环

while是最基本的循环,它的结构为:

while( 布尔表达式 ) {
  //循环内容
}

2. do…while 循环

对于 while 语句而言,如果不满足条件,则不能进入循环。但有时候我们需要即使不满足条件,也至少执行一次。do…while 循环和 while 循环相似,不同的是,do…while 循环至少会执行一次。

do {
       //代码语句
}while(布尔表达式);

**注意:**布尔表达式在循环体的后面,所以语句块在检测布尔表达式之前已经执行了。 如果布尔表达式的值为 true,则语句块一直执行,直到布尔表达式的值为 false

3. for循环

虽然所有循环结构都可以用 while 或者 do...while表示,但 Java 提供了另一种语句 —— for 循环,使一些循环结构变得更加简单。

for循环执行的次数是在执行前就确定的。语法格式如下:

for(初始化; 布尔表达式; 更新) {
    //代码语句
}

关于 for 循环有以下几点说明:

  • 最先执行初始化步骤。可以声明一种类型,但可初始化一个或多个循环控制变量,也可以是空语句。
  • 然后,检测布尔表达式的值。如果为 true,循环体被执行。如果为false,循环终止,开始执行循环体后面的语句。
  • 执行一次循环后,更新循环控制变量。
  • 再次检测布尔表达式。循环执行上面的过程。

4. Java 增强 for 循环

Java5 引入了一种主要用于数组的增强型 for 循环。

Java 增强 for 循环语法格式如下:

for(声明语句 : 表达式)
{
   //代码句子
}

**声明语句:**声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等。

**表达式:**表达式是要访问的数组名,或者是返回值为数组的方法。

5. break 关键字

break 主要用在循环语句或者 switch 语句中,用来跳出整个语句块。

break 跳出最里层的循环,并且继续执行该循环下面的语句。

6. continue 关键字

continue 适用于任何循环控制结构中。作用是让程序立刻跳转到下一次循环的迭代。

for 循环中,continue 语句使程序立即跳转到更新语句。

while 或者 do…while 循环中,程序立即跳转到布尔表达式的判断语句。

7. continue、break 和 return 的区别是什么?

在循环结构中,当循环条件不满足或者循环次数达到要求时,循环会正常结束。但是,有时候可能需要在循环的过程中,当发生了某种条件之后 ,提前终止循环,这就需要用到下面几个关键词:

  1. continue :指跳出当前的这一次循环,继续下一次循环。
  2. break :指跳出整个循环体,继续执行循环下面的语句。

return 用于跳出所在方法,结束该方法的运行。return 一般有两种用法:

  1. return; :直接使用 return 结束方法执行,用于没有返回值函数的方法
  2. return value; :return 一个特定值,用于有返回值函数的方法

思考一下:下列语句的运行结果是什么?

    public static void main(String[] args) {
        boolean flag = false;
        for (int i = 0; i <= 3; i++) {
            if (i == 0) {
                System.out.println("0");
            } else if (i == 1) {
                System.out.println("1");
                continue;
            } else if (i == 2) {
                System.out.println("2");
                flag = true;
            } else if (i == 3) {
                System.out.println("3");
                break;
            } else if (i == 4) {
                System.out.println("4");
            }
            System.out.println("xixi");
        }
        if (flag) {
            System.out.println("haha");
            return;
        }
        System.out.println("heihei");
    }

运行结果:

0
xixi
1
2
xixi
3
haha

五、分支结构

顺序结构只能顺序执行,不能进行判断和选择,因此需要分支结构。

Java有两种分支结构:

  • if语句
  • switch语句

1. if语句

一个if语句包含一个布尔表达式和一条或多条语句。

if语句包括:

  • if...else 语句
  • if...else if...else 语句
  • 嵌套的 if…else 语句

If 语句的用语法如下:

if(布尔表达式)
{
   //如果布尔表达式为true将执行的语句
}

如果布尔表达式的值为 true,则执行if语句中的代码块。否则执行 If 语句块后面的代码。

if...else 语句

if 语句后面可以跟 else 语句,当if语句的布尔表达式值为 false 时,else 语句块会被执行。

if…else 的用法如下:

if(布尔表达式){
   //如果布尔表达式的值为true
}else{
   //如果布尔表达式的值为false
}

if...else if...else 语句

if 语句后面可以跟 else if…else 语句,这种语句可以检测到多种可能的情况。

使用if,else if,else语句的时候,需要注意下面几点:

  • if 语句至多有 1 个 else 语句,else 语句在所有的 else if 语句之后。
  • If 语句可以有若干个 else if 语句,它们必须在 else 语句之前。
  • 一旦其中一个 else if 语句检测为 true,其他的 else if 以及 else 语句都将跳过执行。

语法

if...else 语法格式如下:

if(布尔表达式 1){
   //如果布尔表达式 1的值为true执行代码
}else if(布尔表达式 2){
   //如果布尔表达式 2的值为true执行代码
}else if(布尔表达式 3){
   //如果布尔表达式 3的值为true执行代码
}else {
   //如果以上布尔表达式都不为true执行代码
}

嵌套的 if…else 语句

使用嵌套的 if-else 语句是合法的。也就是说你可以在另一个 if 或者 else if 语句中使用 if 或者 else if 语句。

嵌套的 if…else 语法格式如下:

if(布尔表达式 1){
   ////如果布尔表达式 1的值为true执行代码
   if(布尔表达式 2){
      ////如果布尔表达式 2的值为true执行代码
   }
}

你可以像 if 语句一样嵌套 else if...else。

2. switch 语句

switch 语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支。

switch 语法格式如下:

switch(expression){
    case value :
       //语句
       break; //可选
    case value :
       //语句
       break; //可选
    //你可以有任意数量的case语句
    default : //可选
       //语句
}

switch 语句有如下规则:

  • switch 语句中的变量类型只能为 byte、short、int 或者 char。从 Java SE 7 开始,switch 支持字符串 String 类型了,同时 case 标签必须为字符串常量或字面量。
  • switch 语句可以拥有多个 case 语句。每个 case 后面跟一个要比较的值和冒号。
  • case 语句中的值的数据类型必须与变量的数据类型相同,而且只能是常量或者字面常量。
  • 当变量的值与 case 语句的值相等时,那么 case 语句之后的语句开始执行,直到break语句出现才会跳出 switch 语句。
  • 当遇到 break 语句时,switch 语句终止。程序跳转到 switch 语句后面的语句执行。case 语句不必须要包含break 语句。如果没有 break 语句出现,程序会继续执行下一条 case 语句,直到出现 break 语句。
  • switch 语句可以包含一个 default 分支,该分支必须是 switch 语句的最后一个分支。default 在没有 case 语句的值和变量值相等的时候执行。default 分支不需要 break 语句。

实例:

public class Test {

   public static void main(String args[]){
      //char grade = args[0].charAt(0);
      char grade = 'C';

      switch(grade)
      {
         case 'A' :
            System.out.println("优秀"); 
            break;
         case 'B' :
         case 'C' :
            System.out.println("良好");
            break;
         case 'D' :
            System.out.println("及格");
         case 'F' :
            System.out.println("你需要继续努力");
            break;
         default :
            System.out.println("无效等级");
      }
      System.out.println("你的等级是 " + grade);
   }
}

以上代码编译运行结果如下:

良好
你的等级是 C

六. 数组

数组是相同数据类型的多个数据的容器。这些元素按线性顺序排列。所谓线性顺序是指除第一个元素外,每一个元素都有唯一的前驱元素;除最后一个元素外,每一个元素都有唯一的后继元素。(“简单理解就是:一个跟一个顺序排列”)。

创建格式

格式 1. 数据类型[] 数组名称 = new 数据类型[数组长度];

格式 2. 数据类型[] 数组名称 = {数组内容 1,数组内容 2,数组内容 3...数组内容 n};

格式 3. 数据类型[] 数组名;

格式 3 属于只创建了数组引用名, 并未在内存创建数组空间。

格式 4. 数据类型[] 数组名称 = new 数据类型[]{内容 1,内容 2,内容 3...内容 n};

下标

可以理解为数组中内容的数字序号,从 0 开始 ,对于长度为 n 的数组,下标的范围是 0~n-1。

可以通过下标的方式访问数组中的每一个元素。

例如: 创建 int 类型数组 arr , 给数组 arr 的 5 下标赋值数据 , 然后打印

int[] arr = new int[10];

arr[5] = 123;

System.out.println(arr[5]);

数组长度获取

数组名称.length

注意

使用数组不当, 会出现如下问题:

数组未赋值: 空指针异常

超出长度的下标操作: 数组越界异常

注意:数组的长度在创建时就固定了。

数组常用算法

冒泡排序

原理:

- 比较相邻的元素。如果第一个比第二个大,就交换他们两个。

- 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的

数。

- 针对所有的元素重复以上的步骤,除了最后一个。

- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

名字由来:

是因为最小(或最大)的元素会经由交换慢慢“浮”到数列的顶端(降序或升序),就如同水中的气泡最终会上浮到

顶端一样,故名“冒泡排序”。

升序排列的口诀:

N个数字来排队

两两相比小靠前,

外层 循环length-1

内层循环length-i-1

降序排序的口诀:

N个数字来排队

两两相比大靠前,

外层 循环length-1

内层循环length-i-1

二分查找 (折半查找)

概述

二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,二分查找要求数组数据必须采用顺序存储结构有序排列。

原理

首先,假设数组中元素是按升序排列,将数组中间位置的数据与查找数据比较,如果两者相等,则查找成功;否则利用中间位置记录将数组分成前、后两个子数组,如果中间位置数据大于查找数据,则进一步查找前子数组,否则进一步查找后子数组。

重复以上过程,直到找到满足条件的数据,则表示查找成功,直到子数组不存在为止,表示查找不成功。

数组动态扩容

学习集合知识点时, 重点讲解。

你认为这篇文章怎么样?

  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.14.1