【添油加醋的Java基础】第二章 数据与表达式_基本语法

第二章 数据与表达式

第一节 基本语法元素

Java 标识符【添油加醋的Java基础】第二章 数据与表达式_基本语法_02

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

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

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

Java 修饰符【添油加醋的Java基础】第二章 数据与表达式_基本语法_02

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

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

在后面的章节中我们会深入讨论 Java 修饰符。

Java 变量

Java 中主要有如下几种类型的变量

  • 局部变量
  • 类变量(静态变量)
  • 成员变量(非静态变量)

Java 关键字

下面列出了 Java 关键字。这些保留字不能用于常量、变量、和任何标识符的名称。

Java 注释

类似于 C/C++、Java 也支持单行以及多行注释。

Java 注释主要有三种类型:

  • 单行注释
  • 多行注释
  • 文档注释

注释中的字符将被 Java 编译器忽略。

public class HelloWorld {
   /** 
    * 这是一个文档注释示例
    * 它通常包含有关类、方法或字段的详细信息
    * 这是一个多行注释的示例
    */
    
    /* 
      这也是一个多行
      注释
    */
    public static void main(String[] args){
       // 这是单行注释的示例
       /* 这个也是单行注释的示例 */
       System.out.println("Hello World"); 
    }
}

文档注释以 /** 开始,以 */ 结束,通常出现在类、方法、字段等的声明前面,用于生成代码文档,这种注释可以被工具提取并生成 API 文档,如 JavaDoc。

文档注释的格式通常包含一些特定的标签,如 @param 用于描述方法参数,@return 用于描述返回值,@throws 用于描述可能抛出的异常等等,这些标签有助于生成清晰的API文档,以便其他开发者能够更好地理解和使用你的代码。

Java 空行

空白行或者有注释的行,Java 编译器都会忽略掉。

第二节 基本数据类型

变量就是申请内存来存储值。也就是说,当创建变量的时候,需要在内存中申请空间

内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据。

【添油加醋的Java基础】第二章 数据与表达式_Java_04

因此,通过定义不同类型的变量,可以在内存中储存整数、小数或者字符。

Java 的两大数据类型:

  • 内置数据类型
  • 引用数据类型

内置数据类型

Java语言提供了八种基本类型。六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型。

byte:

  • byte 数据类型是8位、有符号的,以二进制补码表示的整数;
  • 最小值是 -128(-2^7)
  • 最大值是 127(2^7-1)
  • 默认值是 0
  • byte 类型用在大型数组中节约空间,主要代替整数,因为 byte 变量占用的空间只有 int 类型的四分之一;
  • 例子:byte a = 100,byte b = -50。

short:

  • short 数据类型是 16 位、有符号的以二进制补码表示的整数
  • 最小值是 -32768(-2^15)
  • 最大值是 32767(2^15 - 1)
  • Short 数据类型也可以像 byte 那样节省空间。一个short变量是int型变量所占空间的二分之一;
  • 默认值是 0
  • 例子:short s = 1000,short r = -20000。

int:

  • int 数据类型是32位、有符号的以二进制补码表示的整数;
  • 最小值是 -2,147,483,648(-2^31)
  • 最大值是 2,147,483,647(2^31 - 1)
  • 一般地整型变量默认为 int 类型;
  • 默认值是 0
  • 例子:int a = 100000, int b = -200000。

long:

  • long 数据类型是 64 位、有符号的以二进制补码表示的整数;
  • 最小值是 -9,223,372,036,854,775,808(-2^63)
  • 最大值是 9,223,372,036,854,775,807(2^63 -1)
  • 这种类型主要使用在需要比较大整数的系统上;
  • 默认值是 0L
  • 例子: long a = 100000Llong b = -200000L。 "L"理论上不分大小写,但是若写成"l"容易与数字"1"混淆,不容易分辩。所以最好大写。

float:

  • float 数据类型是单精度、32位、符合IEEE 754标准的浮点数;
  • float 在储存大型浮点数组的时候可节省内存空间;
  • 默认值是 0.0f
  • 浮点数不能用来表示精确的值,如货币;
  • 例子:float f1 = 234.5f。

double:

  • double 数据类型是双精度、64 位、符合 IEEE 754 标准的浮点数;
  • 浮点数的默认类型为 double 类型;
  • double类型同样不能表示精确的值,如货币;
  • 默认值是 0.0d
  • 例子:
double   d1  = 7D ;
double   d2  = 7.; 
double   d3  =  8.0; 
double   d4  =  8.D; 
double   d5  =  12.9867;

7 是一个 int 字面量,而 7D,7. 和 8.0 是 double 字面量。

boolean:

  • boolean数据类型表示一位的信息;
  • 只有两个取值:true 和 false;
  • 这种类型只作为一种标志来记录 true/false 情况;
  • 默认值是 false
  • 例子:boolean one = true。

char:

  • char 类型是一个单一的 16 位 Unicode 字符;
  • 最小值是 \u0000(十进制等效值为 0);
  • 最大值是 \uffff(即为 65535);
  • char 数据类型可以储存任何字符;
  • 例子:char letter = 'A';。
实例

对于数值类型的基本类型的取值范围,我们无需强制去记忆,因为它们的值都已经以常量的形式定义在对应的包装类中了。

请看下面的例子:

public class PrimitiveTypeTest {  
    public static void main(String[] args) {  
        // byte  
        System.out.println("基本类型:byte 二进制位数:" + Byte.SIZE);  
        System.out.println("包装类:java.lang.Byte");  
        System.out.println("最小值:Byte.MIN_VALUE=" + Byte.MIN_VALUE);  
        System.out.println("最大值:Byte.MAX_VALUE=" + Byte.MAX_VALUE);  
        System.out.println();  
  
        // short  
        System.out.println("基本类型:short 二进制位数:" + Short.SIZE);  
        System.out.println("包装类:java.lang.Short");  
        System.out.println("最小值:Short.MIN_VALUE=" + Short.MIN_VALUE);  
        System.out.println("最大值:Short.MAX_VALUE=" + Short.MAX_VALUE);  
        System.out.println();  
  
        // int  
        System.out.println("基本类型:int 二进制位数:" + Integer.SIZE);  
        System.out.println("包装类:java.lang.Integer");  
        System.out.println("最小值:Integer.MIN_VALUE=" + Integer.MIN_VALUE);  
        System.out.println("最大值:Integer.MAX_VALUE=" + Integer.MAX_VALUE);  
        System.out.println();  
  
        // long  
        System.out.println("基本类型:long 二进制位数:" + Long.SIZE);  
        System.out.println("包装类:java.lang.Long");  
        System.out.println("最小值:Long.MIN_VALUE=" + Long.MIN_VALUE);  
        System.out.println("最大值:Long.MAX_VALUE=" + Long.MAX_VALUE);  
        System.out.println();  
  
        // float  
        System.out.println("基本类型:float 二进制位数:" + Float.SIZE);  
        System.out.println("包装类:java.lang.Float");  
        System.out.println("最小值:Float.MIN_VALUE=" + Float.MIN_VALUE);  
        System.out.println("最大值:Float.MAX_VALUE=" + Float.MAX_VALUE);  
        System.out.println();  
  
        // double  
        System.out.println("基本类型:double 二进制位数:" + Double.SIZE);  
        System.out.println("包装类:java.lang.Double");  
        System.out.println("最小值:Double.MIN_VALUE=" + Double.MIN_VALUE);  
        System.out.println("最大值:Double.MAX_VALUE=" + Double.MAX_VALUE);  
        System.out.println();  
  
        // char  
        System.out.println("基本类型:char 二进制位数:" + Character.SIZE);  
        System.out.println("包装类:java.lang.Character");  
        // 以数值形式而不是字符形式将Character.MIN_VALUE输出到控制台  
        System.out.println("最小值:Character.MIN_VALUE="  
                + (int) Character.MIN_VALUE);  
        // 以数值形式而不是字符形式将Character.MAX_VALUE输出到控制台  
        System.out.println("最大值:Character.MAX_VALUE="  
                + (int) Character.MAX_VALUE);  
    }  
}

编译以上代码输出结果如下所示:

基本类型:byte 二进制位数:8
包装类:java.lang.Byte
最小值:Byte.MIN_VALUE=-128
最大值:Byte.MAX_VALUE=127

基本类型:short 二进制位数:16
包装类:java.lang.Short
最小值:Short.MIN_VALUE=-32768
最大值:Short.MAX_VALUE=32767

基本类型:int 二进制位数:32
包装类:java.lang.Integer
最小值:Integer.MIN_VALUE=-2147483648
最大值:Integer.MAX_VALUE=2147483647

基本类型:long 二进制位数:64
包装类:java.lang.Long
最小值:Long.MIN_VALUE=-9223372036854775808
最大值:Long.MAX_VALUE=9223372036854775807

基本类型:float 二进制位数:32
包装类:java.lang.Float
最小值:Float.MIN_VALUE=1.4E-45
最大值:Float.MAX_VALUE=3.4028235E38

基本类型:double 二进制位数:64
包装类:java.lang.Double
最小值:Double.MIN_VALUE=4.9E-324
最大值:Double.MAX_VALUE=1.7976931348623157E308

基本类型:char 二进制位数:16
包装类:java.lang.Character
最小值:Character.MIN_VALUE=0
最大值:Character.MAX_VALUE=65535

Float和Double的最小值和最大值都是以科学记数法的形式输出的,结尾的"E+数字"表示E之前的数字要乘以10的多少次方。比如3.14E3就是【添油加醋的Java基础】第二章 数据与表达式_表达式_05,3.14E-3 就是 【添油加醋的Java基础】第二章 数据与表达式_夏明亮_06

实际上,JAVA中还存在另外一种基本类型 void,它也有对应的包装类 java.lang.Void,不过我们无法直接对它们进行操作。

类型默认值

下表列出了 Java 各个类型的默认值:

数据类型

默认值

byte

0

short

0

int

0

long

0L

float

0.0f

double

0.0d

char

'u0000'

String (or any object)

null

boolean

false

示例:

public class Test {
    static boolean bool;
    static byte by;
    static char ch;
    static double d;
    static float f;
    static int i;
    static long l;
    static short sh;
    static String str;
 
    public static void main(String[] args) {
        System.out.println("Bool :" + bool);
        System.out.println("Byte :" + by);
        System.out.println("Character:" + ch);
        System.out.println("Double :" + d);
        System.out.println("Float :" + f);
        System.out.println("Integer :" + i);
        System.out.println("Long :" + l);
        System.out.println("Short :" + sh);
        System.out.println("String :" + str);
    }
}

实例输出结果为:

Bool     :false
Byte     :0
Character:
Double   :0.0
Float    :0.0
Integer  :0
Long     :0
Short    :0
String   :null

引用类型

  • 在Java中,引用类型的变量非常类似于C/C++的指针。引用类型指向一个对象,指向对象的变量是引用变量。这些变量在声明时被指定为一个特定的类型,比如 Employee、Puppy 等。变量一旦声明后,类型就不能被改变了。
  • 对象、数组都是引用数据类型。
  • 所有引用类型的默认值都是null。
  • 一个引用变量可以用来引用任何与之兼容的类型。
  • 例子:Person x = new Person("Zhangsan")。

Java 常量

常量在程序运行时是不能被修改的。

在 Java 中使用 final 关键字来修饰常量,声明方式和变量类似:

final double PI = 3.1415927;

虽然常量名也可以用小写,但为了便于识别,通常使用大写字母表示常量。

字面量可以赋给任何内置类型的变量。例如:

byte a = 68;
char a = 'A'

byte、int、long、和short都可以用十进制、16进制以及8进制的方式来表示。

当使用字面量的时候,前缀 0 表示 8 进制,而前缀 0x 代表 16 进制, 例如:

int decimal = 100;
int octal = 0144;
int hexa =  0x64;

和其他语言一样,Java的字符串常量也是包含在两个引号之间的字符序列。下面是字符串型字面量的例子:

"Hello World"
"two\nlines"
"\"This is in quotes\""

字符串常量和字符变量都可以包含任何 Unicode 字符。例如:

char a = '\u0001';
String a = "\u0001";

Java语言支持一些特殊的转义字符序列。

符号

字符含义

\n

换行 (0x0a)

\r

回车 (0x0d)

\f

换页符(0x0c)

\b

退格 (0x08)

\0

空字符 (0x0)

\s

空格 (0x20)

\t

制表符

\"

双引号

\'

单引号

\\

反斜杠

\ddd

八进制字符 (ddd)

\uxxxx

16进制Unicode字符 (xxxx)

自动类型转换

整型、实型(常量)、字符型数据可以混合运算。运算中,不同类型的数据先转化为同一类型,然后进行运算。

转换从低级到高级。

低  ------------------------------------>  高

byte,short,char—> int —> long—> float —> double

数据类型转换必须满足如下规则:

  1. 不能对boolean类型进行类型转换。
  2. 不能把对象类型转换成不相关类的对象。
  3. 在把容量大的类型转换为容量小的类型时必须使用强制类型转换
  4. 转换过程中可能导致溢出或损失精度,例如:
int i =128;   
byte b = (byte)i;

因为 byte 类型是 8 位,最大值为127,所以当 int 强制转换为 byte 类型时,值 128 时候就会导致溢出。

  1. 浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入,例如:
(int)23.7 == 23;        
(int)-45.89f == -45
自动类型转换

必须满足转换前的数据类型的位数要低于转换后的数据类型,

例如: short数据类型的位数为16位,就可以自动转换位数为32的int类型,同样float数据类型的位数为32,可以自动转换为64位的double类型。

public class ZiDongLeiZhuan{
        public static void main(String[] args){
            char c1='a';//定义一个char类型
            int i1 = c1;//char自动类型转换为int
            System.out.println("char自动类型转换为int后的值等于"+i1);
            char c2 = 'A';//定义一个char类型
            int i2 = c2+1;//char 类型和 int 类型计算
            System.out.println("char类型和int计算后的值等于"+i2);
        }
}

运行结果为:

char自动类型转换为int后的值等于97
char类型和int计算后的值等于66

**解析:**c1 的值为字符 a ,查 ASCII 码表可知对应的 int 类型值为 97, A 对应值为 65,所以 i2=65+1=66

强制类型转换

  1. 条件是转换的数据类型必须是兼容的。
  2. 格式:(type)value type是要强制类型转换后的数据类型 实例:
public class ForceTransform {
    public static void main(String[] args){
        int i1 = 123;
        byte b = (byte)i1;//强制类型转换为byte
        System.out.println("int强制类型转换为byte后的值等于"+b);
    }
}

运行结果:

int强制类型转换为byte后的值等于123

隐含强制类型转换

  1. 整数的默认类型是 int。
  2. 小数默认是 double 类型浮点型,在定义 float 类型时必须在数字后面跟上 F 或者 f。

Java Number & Math 类

Java Number类

一般来说当需要使用数字的时候,我们通常使用内置数据类型,如:byte、int、long、double 等。

int a = 5000;
float b = 13.65f;
byte c = 0x4a;

然而,在实际开发过程中,我们经常会遇到需要使用对象,而不是内置数据类型的情形。为了解决这个问题,Java 语言为每一个内置数据类型提供了对应的包装类。

关于包装类的概念在第四章的第四节有更详细的介绍;可以先看。

【添油加醋的Java基础】第二章 数据与表达式_夏明亮_07

这种由编译器特别支持的包装称为装箱,所以当内置数据类型被当作对象使用的时候,编译器会把内置类型装箱为包装类。相似的,编译器也可以把一个对象拆箱为内置类型。Number 类属于 java.lang 包。

下面是一个使用 Integer 对象的实例:

public class Test{
 
   public static void main(String[] args){
      Integer x = 5;
      x =  x + 10;
      System.out.println(x); 
   }
}

以上实例编译运行结果如下:

15

当 x 被赋为整型值时,由于x是一个对象,所以编译器要对x进行装箱。然后,为了使x能进行加运算,所以要对x进行拆箱。

基本数据类型和它的包装类有什么不同呢?

package com.xml.a;

public class test04 {
	public static void main(String[] args) {
		int a = 10;  // 这个a是基本类型的,它没有属性、方法这些东西
		Integer b = 100;  //这个是包装类Integer类型的,它有额外的丰富的属性和方法可以使用
		a = a + 10;
		b = b + 10;
		System.out.println(a);
		System.out.println(b);
		System.out.println(b.toString());
	}
}

【添油加醋的Java基础】第二章 数据与表达式_基本语法_08


Java Math 类

Java 的 Math 包含了用于执行基本数学运算的属性和方法,如初等指数、对数、平方根和三角函数。

Math 的方法都被定义为 static 形式,通过 Math 类可以在主函数中直接调用。

public class Test {  
    public static void main (String []args)  
    {  
        System.out.println("90 度的正弦值:" + Math.sin(Math.PI/2));  
        System.out.println("0度的余弦值:" + Math.cos(0));  
        System.out.println("60度的正切值:" + Math.tan(Math.PI/3));  
        System.out.println("1的反正切值: " + Math.atan(1));  
        System.out.println("π/2的角度值:" + Math.toDegrees(Math.PI/2));  
        System.out.println(Math.PI);  
    }  
}

以上实例编译运行结果如下:

90 度的正弦值:1.0
0度的余弦值:1.0
60度的正切值:1.7320508075688767
1的反正切值: 0.7853981633974483
π/2的角度值:90.0
3.141592653589793
Number & Math 类方法

下面的表中列出的是 Number & Math 类常用的一些方法:

编号

方法与描述

1

xxxValue()将 Number 对象转换为xxx数据类型的值并返回。

2

compareTo()将number对象与参数比较。

3

equals() 判断number对象是否与参数相等。

4

valueOf() 返回一个 Number 对象指定的内置数据类型

5

toString() 以字符串形式返回值。

6

parseInt() 将字符串解析为int类型。

7

abs() 返回参数的绝对值。

8

ceil() 返回大于等于( >= )给定参数的的最小整数,类型为双精度浮点型。

9

floor() 返回小于等于(<=)给定参数的最大整数 。

10

rint() 返回与参数最接近的整数。返回类型为double。

11

round() 它表示四舍五入,算法为 Math.floor(x+0.5),即将原来的数字加上 0.5 后再向下取整,所以,Math.round(11.5) 的结果为12,Math.round(-11.5) 的结果为-11。

12

min() 返回两个参数中的最小值。

13

max() 返回两个参数中的最大值。

14

exp() 返回自然数底数e的参数次方。

15

log() 返回参数的自然数底数的对数值。

16

pow() 返回第一个参数的第二个参数次方。

17

sqrt() 求参数的算术平方根。

18

sin() 求指定double类型参数的正弦值。

19

cos() 求指定double类型参数的余弦值。

20

tan() 求指定double类型参数的正切值。

21

asin() 求指定double类型参数的反正弦值。

22

acos() 求指定double类型参数的反余弦值。

23

atan() 求指定double类型参数的反正切值。

24

atan2() 将笛卡尔坐标转换为极坐标,并返回极坐标的角度值。

25

toDegrees() 将参数转化为角度。

26

toRadians() 将角度转换为弧度。

27

random() 返回一个随机数。

Java Character 类

Character 类用于对单个字符进行操作。

Character 类在对象中包装一个基本类型 char 的值

char ch = 'a';
 
// Unicode 字符表示形式
char uniChar = '\u039A'; 
 
// 字符数组
char[] charArray ={ 'a', 'b', 'c', 'd', 'e' };

然而,在实际开发过程中,我们经常会遇到需要使用对象,而不是内置数据类型的情况。为了解决这个问题,Java语言为内置数据类型char提供了包装类Character类。

Character类提供了一系列方法来操纵字符。你可以使用Character的构造方法创建一个Character类对象,例如:

Character ch = new Character('a');

在某些情况下,Java编译器会自动创建一个Character对象。

例如,将一个char类型的参数传递给需要一个Character类型参数的方法时,那么编译器会自动地将char类型参数转换为Character对象。 这种特征称为装箱,反过来称为拆箱

// 原始字符 'a' 装箱到 Character 对象 ch 中
Character ch = 'a';
 
// 原始字符 'x' 用 test 方法装箱
// 返回拆箱的值到 'c'
char c = test('x');
转义序列

前面有反斜杠(\)的字符代表转义字符,它对编译器来说是有特殊含义的。

下面列表展示了Java的转义序列:

转义序列

描述

\t

在文中该处插入一个tab键

\b

在文中该处插入一个后退键

\n

在文中该处换行

\r

在文中该处插入回车

\f

在文中该处插入换页符

\'

在文中该处插入单引号

\"

在文中该处插入双引号

\\

在文中该处插入反斜杠

当打印语句遇到一个转义序列时,编译器可以正确地对其进行解释。

以下实例转义双引号并输出:

public class Test {
   public static void main(String[] args) {
      System.out.println("访问\"谷歌!\"");
   }
}

以上实例编译运行结果如下:

访问"谷歌!"
Character 方法

下面是Character类的方法:

序号

方法与描述

1

isLetter() 是否是一个字母

2

isDigit() 是否是一个数字字符

3

isWhitespace() 是否是一个空白字符

4

isUpperCase() 是否是大写字母

5

isLowerCase() 是否是小写字母

6

toUpperCase() 指定字母的大写形式

7

toLowerCase() 指定字母的小写形式

8

toString() 返回字符的字符串形式,字符串的长度仅为1

对于方法的完整列表,请参考的 java.lang.Character API 规范。

Java String 类

字符串广泛应用 在 Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串。

在 Java 中,String 类是用于表示字符串的类,它提供了许多方法用于操作字符串。String 对象是不可变的,即一旦创建,它们的值就不能被更改。(特别注意:这里的不可变并非意味着String类型变量的值就不能改变,这一点可以转到附录C部分详细讲解。)

**注意:**String 类是不可改变的,所以你一旦创建了 String 对象,那它的值就无法改变了。

如果需要对字符串做很多修改,那么应该选择使用 StringBuffer / StringBuilder 类。

创建 String 对象

有几种方式可以创建 String 对象:

  1. 直接赋值
String str1 = "Hello, World!";

通过这种方式创建String 的字符串存储在公共池中,当两个变量的字面值相同时,他们实际上可以看作是引用了相同的内存地址。

而 new 创建的字符串对象在堆上;即使当两个变量的字面值相同时,他们实际上也分别引用不同的内存地址。

  1. 通过构造函数
String str2 = new String("Hello, World!");

这个图很好地说明了他们的区别:

【添油加醋的Java基础】第二章 数据与表达式_基本数据类型_09

常用的 String 方法
1. 获取字符串长度
int length = str1.length();
System.out.println("Length: " + length);  // 输出:Length: 13
2. 字符串拼接
String str3 = str1.concat(" How are you?");
System.out.println(str3);  // 输出:Hello, World! How are you?

或者使用 + 操作符:

String str4 = str1 + " How are you?";
System.out.println(str4);  // 输出:Hello, World! How are you?
3. 字符串比较
  • equals() 方法:比较两个字符串的内容是否相同。
String str5 = "Hello";
String str6 = "hello";
boolean isEqual = str5.equals(str6);
System.out.println(isEqual);  // 输出:false
  • equalsIgnoreCase() 方法:比较两个字符串的内容是否相同,忽略大小写。
boolean isEqualIgnoreCase = str5.equalsIgnoreCase(str6);
System.out.println(isEqualIgnoreCase);  // 输出:true
4. 获取字符串中的字符
char ch = str1.charAt(0);
System.out.println(ch);  // 输出:H
5. 查找子字符串
  • indexOf() 方法:返回指定子字符串的第一次出现的索引。
int index = str1.indexOf("World");
System.out.println(index);  // 输出:7
  • lastIndexOf() 方法:返回指定子字符串的最后一次出现的索引。
int lastIndex = str1.lastIndexOf("o");
System.out.println(lastIndex);  // 输出:8
6. 子字符串
  • substring() 方法:返回从指定索引开始到结束的子字符串。
String subStr1 = str1.substring(7);
System.out.println(subStr1);  // 输出:World!

String subStr2 = str1.substring(7, 12);
System.out.println(subStr2);  // 输出:World
7. 转换大小写
String upperStr = str1.toUpperCase();
System.out.println(upperStr);  // 输出:HELLO, WORLD!

String lowerStr = str1.toLowerCase();
System.out.println(lowerStr);  // 输出:hello, world!
8. 去除空格
  • trim() 方法:去除字符串前后的空格。
String str7 = "   Hello, World!   ";
String trimmedStr = str7.trim();
System.out.println(trimmedStr);  // 输出:Hello, World!
9. 替换字符或子字符串
  • replace() 方法:替换所有指定的字符。
String replacedStr = str1.replace('o', 'a');
System.out.println(replacedStr);  // 输出:Hella, Warld!
  • replaceAll() 方法:替换所有匹配正则表达式的子字符串。
String replacedAllStr = str1.replaceAll("World", "Java");
System.out.println(replacedAllStr);  // 输出:Hello, Java!
10. 分割字符串
  • split() 方法:将字符串分割为字符串数组。
String[] words = str1.split(" ");
for (String word : words) {
    System.out.println(word);
}
// 输出:
// Hello,
// World!
示例代码

以下是一个完整的示例,展示了如何使用上述方法:

public class StringExample {
    public static void main(String[] args) {
        // 创建字符串
        String str1 = "Hello, World!";
        String str2 = new String("Hello, Java!");

        // 获取字符串长度
        System.out.println("Length of str1: " + str1.length());

        // 字符串拼接
        String str3 = str1.concat(" How are you?");
        System.out.println("Concatenated String: " + str3);

        // 字符串比较
        System.out.println("str1 equals str2: " + str1.equals(str2));
        System.out.println("str1 equalsIgnoreCase str2: " + str1.equalsIgnoreCase("hello, world!"));

        // 获取字符
        System.out.println("Character at index 0 in str1: " + str1.charAt(0));

        // 查找子字符串
        System.out.println("Index of 'World' in str1: " + str1.indexOf("World"));
        System.out.println("Last index of 'o' in str1: " + str1.lastIndexOf("o"));

        // 子字符串
        System.out.println("Substring from index 7: " + str1.substring(7));
        System.out.println("Substring from index 7 to 12: " + str1.substring(7, 12));

        // 转换大小写
        System.out.println("str1 to upper case: " + str1.toUpperCase());
        System.out.println("str1 to lower case: " + str1.toLowerCase());

        // 去除空格
        String str4 = "   Hello, World!   ";
        System.out.println("Trimmed str4: '" + str4.trim() + "'");

        // 替换字符
        System.out.println("Replace 'o' with 'a' in str1: " + str1.replace('o', 'a'));
        System.out.println("Replace 'World' with 'Java' in str1: " + str1.replaceAll("World", "Java"));

        // 分割字符串
        String[] words = str1.split(" ");
        System.out.println("Splitting str1:");
        for (String word : words) {
            System.out.println(word);
        }
    }
}

String 类是 Java 中非常重要的类,用于表示和操作字符串。它是不可变的,提供了丰富的方法来处理字符串。掌握这些方法可以帮助开发者更高效地进行字符串操作。

补充:重点说说字符串的比较

一个例子:

package com.xml.a;

public class test05 {
	public static void main(String[] args) {
		String a = "hello";
		String b = "world!";
		String c = "hello";
		System.out.println(a == b); // false;字面值都不同,肯定false
		System.out.println(a.equals(b)); //false;字面值都不同,肯定false
		System.out.println(a == c); // true;字面值相同且引用相同的内存地址
		System.out.println(a.equals(c)); //true;字面值相同,不要求引用相同的内存地址
		
		a = "nihao";  // 实际上是创建了新的对象
		System.out.println(a); // 输出:nihao;
		
		// 重点
		String x = new String("xiamingliang");
		String y = new String("xiamingliang");
		System.out.println(x == y);  // false;字面值相同且引用相同的内存地址
		System.out.println(x.equals(y)); // true;字面值相同,不要求引用相同的内存地址
	}
}

在Java中,比较对象时使用==equals会产生不同的结果,因为它们的比较方式不同。

String x = new String("xiamingliang"); String y = new String("xiamingliang");

代码分别创建了两个新的String对象。虽然它们的内容相同,但由于new关键字的使用,它们被分配在不同的内存地址。

== 运算符
  • 比较的是对象的引用。它检查两个引用是否指向同一个对象(即内存地址是否相同)。
  • xy是两个不同的String对象,虽然它们的内容相同,但它们在内存中的地址不同。因此,x == y结果为false
equals 方法
  • 比较的是对象的内容。它检查两个对象的内容是否相同。
  • String类重写了equals方法,使其比较字符串的字符序列是否相同。
  • x.equals(y)比较的是xy的内容。由于xy的内容都是"xiamingliang",所以结果为true

Java StringBuffer 和 StringBuilder 类

他们的区别与联系

当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。

和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。

【添油加醋的Java基础】第二章 数据与表达式_夏明亮_10

在使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,所以如果需要对字符串进行修改推荐使用 StringBuffer

StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。

由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。

StringBuilder 使用示例
package com.xml.a;

public class Test06 {
	public static void main(String args[]){
        StringBuilder sb = new StringBuilder(10);
        sb.append("Hello..");
        System.out.println(sb);  // Hello..
        sb.append("!");
        System.out.println(sb);  // Hello..!
        sb.insert(6, "Java");
        System.out.println(sb);  // Hello.Java.!
        sb.delete(5,8);
        System.out.println(sb);  // Hellova.!
    }
}

【添油加醋的Java基础】第二章 数据与表达式_基本数据类型_11

然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。


StringBuffer 方法

以下是 StringBuffer 类支持的主要方法:

序号

方法描述

1

public StringBuffer append(String s) 将指定的字符串追加到此字符序列。

2

public StringBuffer reverse() 将此字符序列用其反转形式取代。

3

public delete(int start, int end) 移除此序列的子字符串中的字符。

4

public insert(int offset, int i)int 参数的字符串表示形式插入此序列中。

5

insert(int offset, String str)str 参数的字符串插入此序列中。

6

replace(int start, int end, String str) 使用给定 String 中的字符替换此序列的子字符串中的字符。

以下列表列出了 StringBuffer 类的其他常用方法:

序号

方法描述

1

int capacity() 返回当前容量。

2

char charAt(int index) 返回此序列中指定索引处的 char 值。

3

void ensureCapacity(int minimumCapacity) 确保容量至少等于指定的最小值。

4

void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) 将字符从此序列复制到目标字符数组 dst

5

int indexOf(String str) 返回第一次出现的指定子字符串在该字符串中的索引。

6

int indexOf(String str, int fromIndex) 从指定的索引处开始,返回第一次出现的指定子字符串在该字符串中的索引。

7

int lastIndexOf(String str) 返回最右边出现的指定子字符串在此字符串中的索引。

8

int lastIndexOf(String str, int fromIndex) 返回 String 对象中子字符串最后出现的位置。

9

int length() 返回长度(字符数)。

10

void setCharAt(int index, char ch) 将给定索引处的字符设置为 ch

11

void setLength(int newLength) 设置字符序列的长度。

12

CharSequence subSequence(int start, int end) 返回一个新的字符序列,该字符序列是此序列的子序列。

13

String substring(int start) 返回一个新的 String,它包含此字符序列当前所包含的字符子序列。

14

String substring(int start, int end) 返回一个新的 String,它包含此序列当前所包含的字符子序列。

15

String toString() 返回此序列中数据的字符串表示形式。

第三节 表达式

Java 变量类型

在 Java 语言中,所有的变量在使用前必须声明。

声明变量的基本格式如下:

type name1 [ = value1][, name2 [= value2] ...] ;

格式说明:

  • type -- 数据类型。
  • namex-- 是变量名,可以使用逗号 , 隔开来声明多个同类型变量。

以下列出了一些变量的声明实例。注意有些包含了初始化过程。

int a, b, c;         // 声明三个int型整数:a、 b、c
int d = 3, e = 4, f = 5; // 声明三个整数并赋予初值
byte z = 22;         // 声明并初始化 z
String s = "hello";  // 声明并初始化字符串 s
double pi = 3.14159; // 声明了双精度浮点型变量 pi
char x = 'x';        // 声明变量 x 的值是字符 'x'。

Java 语言支持的变量类型有:

局部变量(Local Variables):

局部变量是在方法构造函数块内部声明的变量,它们在声明的方法、构造函数或块执行结束后被销毁,局部变量在声明时需要初始化,否则会导致编译错误。

package com.xml.a;

public class test01 {
	public static void main(String[] x) {
		int a;
		//System.out.println(a); // 这样是不对的,局部变量在没有初始化前是不能使用的
		a = 10;
		System.out.println(a);

	}
}
实例变量(Instance Variables):

实例变量是在类中声明,但在方法、构造函数或块之外,它们属于类的实例,每个类的实例都有自己的副本,如果不明确初始化,实例变量会被赋予默认值(数值类型为0,boolean类型为false,对象引用类型为null)。

package com.xml.a;

public class test01 {
	public static void main(String[] x) {
		int a;
		//System.out.println(a); // 这样是不对的,局部变量在没有初始化前是不能使用的
		a = 10;
		System.out.println(a);
		
		
		// 实例化一个对象
		testx obj01 = new testx();
		System.out.println(obj01.a);  //这里实例化对象obj01访问的变量没有经过显式底初始化,但是因为它是示例变量,会被默认构造函数自动赋予初始值。

	}
}

class testx{
	int a;
}
静态变量或类变量(Class Variables):

类变量是在类中用 static 关键字声明的变量,它们属于类而不是实例,所有该类的实例共享同一个类变量的值,类变量在类加载时被初始化,而且只初始化一次。

静态变量的生命周期与程序的生命周期一样长,即它们在类加载时被创建,在整个程序运行期间都存在,直到程序结束才会被销毁。因此,静态变量可以用来存储整个程序都需要使用的数据,如配置信息、全局变量等。

package com.xml.a;

public class test01 {
	public static void main(String[] x) {
		int a;
		//System.out.println(a); // 这样是不对的,局部变量在没有初始化前是不能使用的
		a = 10;
		System.out.println(a);
		

		System.out.println("----------");
		// 直接使用类中的静态变量,也叫类变量
		System.out.println(testy.a);   // 0;无需实例化,即可直接访问
		// 实例化一个对象
		testy obj02 = new testy();
		System.out.println(obj02.a);  // 0;虽然能访问,但是是不建议这样做的
		// 修改静态变量的值
		testy.a = 20;
		System.out.println(testy.a);  // 20
		System.out.println(obj02.a);  // 20;修改后之前初始化的实例该变量也会改变。虽然能访问,但是是不建议这样做的
		
		// 修改后实例化一个对象
		testy obj03 = new testy();
		System.out.println(obj03.a);  // 20;之后实例化的对象值也是新的,虽然能访问,但是是不建议这样做的
	}
}


class testy{
	static int a;
}
参数变量(Parameters):

参数是方法或构造函数声明中的变量,用于接收调用该方法或构造函数时传递的值,参数变量的作用域只限于方法内部。

public void exampleMethod(parameterType parameterName) {  //这里的parameterName就是参数变量
    // 参数变量
    // ...
}

Java 中的参数变量是指在方法或构造函数中声明的变量,用于接收传递给方法或构造函数的值。参数变量与局部变量类似,但它们只在方法或构造函数被调用时存在,并且只能在方法或构造函数内部使用。

  • parameterName -- 表示参数变量的名称。
  • parameterType -- 表示参数变量的类型。

在调用方法时,我们必须为参数变量传递值,这些值可以是常量、变量或表达式。

方法参数变量的值传递方式有两种:值传递引用传递

  • **值传递:**在方法调用时,传递的是实际参数的值的副本。当参数变量被赋予新的值时,只会修改副本的值,不会影响原始值。Java 中的基本数据类型都采用值传递方式传递参数变量的值。
  • **引用传递:**在方法调用时,传递的是实际参数的引用(即内存地址)。当参数变量被赋予新的值时,会修改原始值的内容。Java 中的对象类型采用引用传递方式传递参数变量的值。
参数变量-值传递

示例:

package com.xml.a;

public class test03 {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        System.out.println("Before swap: a = " + a + ", b = " + b);
        swap(a, b);
        System.out.println("After swap: a = " + a + ", b = " + b);  // 值不变
    }

    public static void swap(int x, int y) {
        int temp = x;
        x = y;
        y = temp;
    }
}

结果:

Before swap: a = 10, b = 20
After swap: a = 10, b = 20
参数变量-引用传递

示例:

public class test02 {
	public static void main(String[] x) {
		String[] test = {"hello", "world"};
		System.out.println("Before Swap:" + test[0] + ", " + test[1]);
		swap(test);
		System.out.println("Before Swap:" + test[0] + ", " + test[1]); // test发生了变化
	}
	
	public static void swap(String[] str) {
		String temp = str[0];
		str[0] = str[1];
		str[1] = temp;
	}

}

结果:

Before Swap:hello, world
After Swap:world, hello
常量和静态变量的区别

常量也是与类相关的,但它是用 final 关键字修饰的变量,一旦被赋值就不能再修改。与静态变量不同的是,常量在编译时就已经确定了它的值,而静态变量的值可以在运行时改变。另外,常量通常用于存储一些固定的值,如数学常数、配置信息等,而静态变量通常用于存储可变的数据,如计数器、全局状态等。

总之,静态变量是与类相关的变量,具有唯一性和共享性,可以用于存储整个程序都需要使用的数据,但需要注意初始化时机和与常量的区别。

Java 修饰符

Java语言提供了很多修饰符,主要分为以下两类:

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

修饰符用来定义类、方法或者变量,通常放在语句的最前端。我们通过下面的例子来说明:

public class ClassName {
   // ...
}
private boolean myFlag;
static final double weeks = 9.5;
protected static final int BOXWIDTH = 42;
public static void main(String[] arguments) {
   // 方法体
}
访问控制修饰符

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

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

我们可以通过以下表来说明访问权限:

修饰符

当前类

同一包内

子孙类(同一包)

子孙类(不同包)

其他包

public

Y

Y

Y

Y

Y

protected

Y

Y

Y

Y/N

N

default

Y

Y

Y

N

N

private

Y

N

N

N

N

protected 需要从以下两个点来分析说明:

  • 子类与基类在同一包中:被声明为 protected 的变量、方法和构造器能被同一个包中的任何其他类访问;
  • 子类与基类不在同一包中:那么在子类中,子类实例可以访问其从基类继承而来的 protected 方法,而不能访问基类实例的protected方法。
访问控制和继承

请注意以下方法继承的规则:

  • 父类中声明为 public 的方法在子类中也必须为 public。
  • 父类中声明为 protected 的方法在子类中要么声明为 protected,要么声明为 public,不能声明为 private。
  • 父类中声明为 private 的方法,不能够被子类继承。
非访问修饰符

为了实现一些其他的功能,Java 也提供了许多非访问修饰符。

  • static 修饰符,用来修饰类方法和类变量。
  • final 修饰符,用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。
  • abstract 修饰符,用来创建抽象类和抽象方法。
  • synchronized 和 volatile 修饰符,主要用于线程的编程。
static 修饰符
  • 静态变量:
    static 关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。 静态变量也被称为类变量。局部变量不能被声明为 static 变量。
  • 静态方法:
    static 关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。静态方法从参数列表得到数据,然后计算这些数据。

对类变量和方法的访问可以直接使用 classname.variablenameclassname.methodname 的方式访问。

final 修饰符

final 变量:

final 表示"最后的、最终的"含义,变量一旦赋值后,不能被重新赋值。被 final 修饰的实例变量必须显式指定初始值

final 修饰符通常和 static 修饰符一起使用来创建类常量。

final 方法

父类中的 final 方法可以被子类继承,但是不能被子类重写

声明 final 方法的主要目的是防止该方法的内容被修改。

final 类

final 类不能被继承,没有类能够继承 final 类的任何特性。

abstract 修饰符

抽象类:

抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。

一个类不能同时被 abstract 和 final 修饰。如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则将出现编译错误。

抽象类可以包含抽象方法和非抽象方法。

抽象方法:

抽象方法是一种没有任何实现的方法,该方法的具体实现由子类提供。

抽象方法不能被声明成 final 和 static。

任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。

如果一个类包含若干个抽象方法,那么该类必须声明为抽象类。抽象类可以不包含抽象方法。

抽象方法的声明以分号结尾,例如:public abstract sample();

synchronized 修饰符

synchronized 关键字声明的方法同一时间只能被一个线程访问。synchronized 修饰符可以应用于四个访问修饰符。

transient 修饰符(短暂的)

序列化的对象包含被 transient 修饰的实例变量时,java 虚拟机(JVM)跳过该特定的变量。

该修饰符包含在定义变量的语句中,用来预处理类和变量的数据类型。

volatile 修饰符(易变的)

volatile 修饰的成员变量在每次被线程访问时都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。

一个 volatile 对象引用可能是 null。

一个常见的用法示例:

public class MyRunnable implements Runnable
{
    private volatile boolean active;
    public void run()
    {
        active = true;
        while (active) // 第一行
        {
            // 代码
        }
    }
    public void stop()
    {
        active = false; // 第二行
    }
}

Java 运算符

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

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

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

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

操作符

描述

例子

+

加法 - 相加运算符两侧的值

A + B 等于 30

-

减法 - 左操作数减去右操作数

A – B 等于 -10

*

乘法 - 相乘操作符两侧的值

A * B等于200

/

除法 - 左操作数除以右操作数

B / A等于2

取余 - 左操作数除以右操作数的余数

B%A等于0

++

自增: 操作数的值增加1

B++ 或 ++B 等于 21(区别详见下文)

--

自减: 操作数的值减少1

B-- 或 --B 等于 19(区别详见下文)

自增自减运算符

1、自增(++)自减(--)运算符是一种特殊的算术运算符,在算术运算符中需要两个操作数来进行运算,而自增自减运算符是一个操作数。

2、前缀自增自减法(++a,--a): 先进行自增或者自减运算,再进行表达式运算。

3、后缀自增自减法(a++,a--): 先进行表达式运算,再进行自增或者自减运算。

public class selfAddMinus{
    public static void main(String[] args){
        int a = 5;//定义一个变量;
        int b = 5;
        int x = 2*++a;  // 拆分为:a=a+1,x=2*a
        int y = 2*b++;  // 拆分为:y=2*b,b=b+1
        System.out.println("自增运算符前缀运算后a="+a+",x="+x);
        System.out.println("自增运算符后缀运算后b="+b+",y="+y);
    }
}

运行结果为:

自增运算符前缀运算后a=6,x=12
自增运算符后缀运算后b=6,y=10
关系运算符

下表为Java支持的关系运算符。

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

位运算符

运算符

描述

例子

==

检查如果两个操作数的是否相等,如果相等则条件为真。

(A == B)为假。

!=

检查如果两个操作数的值是否相等,如果值不相等则条件为真。

(A != B) 为真。

>

检查左操作数的值是否大于右操作数的值,如果是那么条件为真。

(A> B)为假。

<

检查左操作数的值是否小于右操作数的值,如果是那么条件为真。

(A <B)为真。

>=

检查左操作数的值是否大于或等于右操作数的值,如果是那么条件为真。

(A> = B)为假。

<=

检查左操作数的值是否小于或等于右操作数的值,如果是那么条件为真。

(A <= B)为真。

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

^

如果相对应位值相同,则结果为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

逻辑运算符

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

操作符

描述

例子

&&

称为逻辑与运算符。当且仅当两个操作数都为真,条件才为真。

(A && B)为假。

`


`

称为逻辑非运算符。用来反转操作数的逻辑状态。如果条件为true,则逻辑非运算符将得到false。

!(A && B)为真。

短路逻辑运算符

当使用与逻辑运算符时,在两个操作数都为true时,结果才为true,但是当得到第一个操作为false时,其结果就必定是false,这时候就不会再判断第二个操作了。

public class LuoJi{
    public static void main(String[] args){
        int a = 5;//定义一个变量;
        boolean b = (a<4)&&(a++<10);  // 使用到了短路逻辑运算符(&&),首先判断 a<4 的结果为 false,则 b 的结果必定是 false,所以不再执行第二个操作 a++<10 的判断,所以 a 的值为 5。
        System.out.println("使用短路逻辑运算符的结果为"+b);
        System.out.println("a的结果为"+a);
    }
}
赋值运算符

下面是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

%=

取模和赋值操作符,它把左操作数和右操作数取模后赋值给左操作数

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

`

=`

按位或赋值操作符

条件运算符(?:)

条件运算符也被称为三元运算符。该运算符有3个操作数,并且需要判断布尔表达式的值。该运算符的主要是决定哪个值应该赋值给变量。

public class Test {
   public static void main(String[] args){
      int a , b;
      a = 10;
      // 如果 a 等于 1 成立,则设置 b 为 20,否则为 30
      b = (a == 1) ? 20 : 30;
      System.out.println( "Value of b is : " +  b );
 
      // 如果 a 等于 10 成立,则设置 b 为 20,否则为 30
      b = (a == 10) ? 20 : 30;
      System.out.println( "Value of b is : " + b );
   }
}
instanceof 运算符

该运算符用于操作对象实例,检查该对象是否是一个特定类型(类类型或接口类型)。

instanceof运算符使用格式如下:

( Object reference variable ) instanceof  (class/interface type)

如果运算符左侧变量所指的对象,是操作符右侧类或接口(class/interface)的一个对象,那么结果为真。

下面是一个例子:

String name = "James";
boolean result = name instanceof String; // 由于 name 是 String 类型,所以返回真

如果被比较的对象兼容于右侧类型,该运算符仍然返回 true。

Java运算符优先级

当多个运算符出现在一个表达式中,谁先谁后呢?这就涉及到运算符的优先级别的问题。在一个多运算符的表达式中,运算符优先级不同会导致最后得出的结果差别甚大。

例如,【添油加醋的Java基础】第二章 数据与表达式_Java_12,这个表达式如果按加号最优先计算,答案就是 18,如果按照乘号最优先,答案则是 14。

再如,【添油加醋的Java基础】第二章 数据与表达式_夏明亮_13;这里x得到13,而不是20,因为乘法运算符比加法运算符有较高的优先级,所以先计算3 * 2得到6,然后再加7。

下表中具有最高优先级的运算符在的表的最上面,最低优先级的在表的底部。

类别

操作符

关联性

后缀

() [] . (点操作符)

左到右

一元

expr++ expr--

从左到右

一元

++expr --expr + - ~ !

从右到左

乘性

* /%

左到右

加性

+ -

左到右

移位

>> >>> <<

左到右

关系

> >= < <=

左到右

相等

== !=

左到右

按位与


左到右

按位异或

^

左到右

按位或

|

左到右

逻辑与

&&

左到右

逻辑或

| |

左到右

条件

?:

从右到左

赋值

= + = - = * = / =%= >> = << =&= ^ = | =

从右到左

逗号


左到右

本章小结

习题