第二课:基本语法
一个 Java 程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作。
- 对象:对象是类的一个实例,有状态和行为。例如,黑白的的小猫咪咪是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。
- 类:类是一个模板,它描述一类对象的行为和状态。如所有的量产黑白小猫都是一个类
- 方法:方法就是行为,一个类可以有很多方法。逻辑运算、数据修改以及所有动作都是在方法中完成的。
- 实例变量:每个对象都有独特的实例变量,对象的状态由这些实例变量的值决定。
(一)Hello World
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World"); // 输出 Hello World
}
}
把文件名保存为:HelloWorld.java ( 源文件名必须和类名相同,大小写也一样!文件名的后缀为 .java)
在当前路径输入命令 编译代码
javac HelloWorld.java
或者
javac -encoding UTF-8 HelloWorld.java
我们会看到在当前目录下生成了一个 class 文件:HelloWorld.class
运行程序
java HelloWorld
你将会在窗口看到 Hello World
这段代码的运行流程是这样的:
-
public static void main(String[] args) 是 Java 程序的 入口 方法,JVM 从这里开始执行。
-
Java 是 先编译再执行 的语言,
javac编译器 将其转换为 字节码(Bytecode),生成 字节码文件HelloWorld.class(这个文件是 JVM 可执行的格式) -
运行时,JVM 读取
HelloWorld.class,并加载到 方法区(Method Area) -
JVM 确保
.class文件没有安全漏洞(防止恶意代码) -
JVM 解释并执行 .class 文件中的 字节码。 可能会把热点代码转换为 机器码(提升性能)。
-
JVM 解释执行 Java 字节码,将其转换为操作系统能理解的指令。
-
Java 内部调用
PrintStream对象的println()方法,将"Hello World"输出到控制台。 -
main()方法执行结束,JVM 关闭,程序退出。
注意:
Java 代码是 跨平台 的,因为它不直接运行在 CPU 上,而是运行在 JVM 内部
Windows / Mac / Linux 上的 JVM 都能运行 相同的
.class文件Java 代码比 C 代码多了一个 JVM 转换步骤
- C 语言:直接编译成机器码 → CPU 执行
- Java:编译成字节码 → JVM 翻译成机器码 → CPU 执行
Java 源程序与编译型运行区别

(二)类和对象
Java 是一门基于类的语言,几乎所有的代码都是围绕类和对象组织的。
类(Class)可以看成是创建 对象(Object)的模板。
1. 类和对象的定义
在 Java 中,类的定义遵循以下格式:
class 类名 { //注意类后面没有括号!
// 属性(成员变量)
数据类型 变量名;
// 方法(成员方法)
返回类型 方法名(参数列表) {
// 方法体
}
}
示例:定义一个简单的类
class Car {
// 属性(成员变量)
String brand; // 品牌
int speed; // 速度
// 方法(成员方法)
void accelerate() {
speed += 10;
System.out.println(brand + " 加速了,现在速 度是 " + speed + " km/h");
}
}
**对象(Object)**是类的一个实例(Instance)。换句话说,类是抽象的,而对象是具体的。
在 Java 中,使用 new 关键字来创建对象:
类名 对象名 = new 类名();
示例:创建对象并使用它
public class Main {
public static void main(String[] args) {
// 创建对象
Car myCar = new Car(); //创建了 `Car` 类的一个实例 `myCar`。
// 给对象的属性赋值
myCar.brand = "Toyota";
myCar.speed = 50;
// 调用对象的方法
myCar.accelerate(); // 输出: Toyota 加速了,现在速度是 60 km/h
}
}
在这 里我们可以看到定义类 和 变量的 语法

2. 类的四大特性
-
继承(Inheritance):
-
允许一个类继承另一个类的属性和方法,增强代码复用性。
-
关键字:
extends -
示例
class Animal { void makeSound() { System.out.println("动物发出声音"); } } class Dog extends Animal { void bark() { System.out.println("汪汪汪"); } } public class Main { public static void main(String[] args) { Dog myDog = new Dog(); myDog.makeSound(); // 继承父类方法 myDog.bark(); } }
-
-
封装(Encapsulation):
-
通过
private修饰变量,提供public方法访问,提高安全性。 -
示例
class Person{ private String name; public void setName(String newName){ name = newName; } public String getName(){ return name; } } public class Main { public static void main(String[] args){ Person person = new Person(); System.out.println("改名字之前:" + person.getName()); // 输出 null person.setName("Heihe"); // System.out.println(person.name); //直接访问 person 的 name 属性会报错 System.out.println("改名字之后:" + person.getName()); } }
-
-
多态(Polymorphism):
-
方法重载(Overloading): 在同一个类中,同名方法可以有不同的参数列表。
-
方法重写(Overriding): 子类可以重写父类的方法,实现不同的行为。
-
示例
class Animal { void makeSound() { System.out.println("动物发出声音"); } } class Cat extends Animal { @Override void makeSound() { System.out.println("喵喵喵"); } }
-
-
抽象(Abstraction):
-
通过 抽象类(abstract class) 或 接口(interface) 实现。
-
示例
abstract class Shape { abstract void draw(); // 抽象方法 } class Circle extends Shape { void draw() { System.out.println("画一个圆"); } }
-
3. 构造方法(Constructor)
构造方法 用于在创建对象时初始化对象的属性。
构造方法的特点
- 方法名必须与类名相同。
- 没有返回值(甚至不能写
void)。 - 可以有参数,用来在创建对象时赋值。
- 如果你不定义构造方法,Java 会自动创建一个无参构造
- 每次使用
new创建对象时,构造方法会被自动调用。 - 构造方法不能像普通方法那样被直接调用 ,只能通过
new来触发。 - 一个类可以定义多个构造方法(构造方法重载),只要参数列表不同即可(详见“方法的特性”)
- 构造方法不能被子类继承,但可以通过
super()调用父类的构造方法。
示例:定义构造方法
class Cat {
String name;
int weight;
Cat(String name, int weight ){
this.name=name;
this.weight=weight;
}
}
public class Main {
public static void main(String[] args){
Cat cat= new Cat("mimi",56);
System.out.println(cat.name);
System.out.println(cat.weight);
}
}
这里有个地方需要注意,为什么在写构造函数的时候要用
this.?不用会怎么样?如果不用,会没法成功赋值,输出的分别是 null 和 0 ,也就是默认值。
这是因为 左边的
size和wight是局部变量(构造方法的参数),而不是类的成员变量换句话说,java不会把等号左边 的
size和wight当成是类的属性,而当成新建的局部变量而加上
this.之后,实际上是类的属性
可以使用 this() 调用当前类的其他构造方法。
调用 this() 时,必须放在构造方法中的第一行。
示例:
public class Person {
String name;
int age;
// 构造方法调用
public Person(String name) {
this(name, 0); // 调用双参数的构造方法
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
调用实例:
Person p = new Person("Alice"); // 调用了单参数构造方法,进而调用双参数构造方法
System.out.println(p.name); // 输出:Alice
System.out.println(p.age); // 输出:0
super() 调用父类构造方法:
- 子类的构造方法可通过
super()调用父类的构造方法(必须是第一行)。 - 如果未显式调用父类的构造方法,系统会自动插入对父类无参构造方法的调用。
4. 访问修饰符
Java 提供了四种访问权限控制:
| 修饰符 | 作用范围 | 说明 |
|---|---|---|
public | 任何地方可访问 | 最高权限 |
private | 仅限当前类内访问 | 只能在本类使用 |
protected | 当前类、同包内的类和子类可访问 | 适用于继承 |
| (默认,无修饰符) | 仅限当前包内访问 | 不能被外部包访问 |
示例
class Car {
private String brand; // 只能在 Car 类内部访问
public int speed; // 任何地方都可以访问
// 构造方法
Car(String b, int s) {
this.brand = b;
this.speed = s;
}
// 通过方法访问私有变量
public String getBrand() {
return brand;
}
}
public class Main {
public static void main(String[] args) {
Car myCar = new Car("BMW", 100);
// 访问 public 变量
System.out.println("速度: " + myCar.speed); // 可以访问
// 访问 private 变量(必须通过方法)
System.out.println("品牌: " + myCar.getBrand()); // 不能直接访问 brand
}
}
在这里:
brand被private修饰,不能在Main类中直接访问,只能通过getBrand()获取。speed被public修饰,可以直接访问。
5. 变量类型
前面一点讲到了变量的访问权限控制,其实变量本身有三种分类:
| 变量类型 | 存储位置 | 作用域 | 默认值 |
|---|---|---|---|
| 局部变量 | 栈 | 方法内部 | 无(必须手动初始化) |
| 实例变量 | 堆 | 属于对象 | 0、false、null |
| 静态变量 | 方法区 | 属于类 | 0、false、null |
- 局部变量(Local Variable):定义在方法、构造方法或代码块内部,生命周期仅限于该方法内。
- 成员变量(Instance Variable):定义在类中但在方法外,是当前对象的实例变量
- 类变量(Static Variable):使用
static声明,是属于 整个类 的,而不是某个特定的对象,所有对象共享一份数据。 适用于存储所有对象共享的信息,比如统计创建了多少个实例 等
示例
public class Puppy {
// 实例变量(每个对象独立)
private int age;
private String name;
// 类变量(所有对象共享)
private static int count = 0; // 统计创建的 Puppy 对象个数
private static String species = "Dog A"; // 共享种类信息
// 构造方法
public Puppy(String n) {
this.name = n; // n 是局部变量
count++; // 每创建一个 Puppy 对象,count 自增
}
// Setter 方法
public void setAge(int a) {
this.age = a; // a 是局部变量
//由于变量名不同,这里可以直接写:age = a;
}
// Getter 方法
public int getAge() {
return age;
}
public String getName() {
return name;
}
// 类变量的 setter 方法
public static void setSpecies(String newSpecies) {
species = newSpecies;
}
// 类变量的 getter 方法
public static int getCount() {
return count;
}
public static String getSpecies() {
return species;
}
// 主程序
public static void main(String[] args) {
Puppy puppy1 = new Puppy("Tommy");
puppy1.setAge(2);
Puppy puppy2 = new Puppy("Charlie");
puppy2.setAge(3);
System.out.println("小狗1的名字是: " + puppy1.getName());
System.out.println("小狗1的年龄是: " + puppy1.getAge());
System.out.println("小狗2的名字是: " + puppy2.getName());
System.out.println("小狗2的年龄是: " + puppy2.getAge());
// 访问类变量
System.out.println("Puppy 的种类是: " + Puppy.getSpecies());
System.out.println("当前创建的小狗总数: " + Puppy.getCount());
// 修改类变量(影响所有对象)
Puppy.setSpecies("Dog B");
System.out.println("更新后的 Puppy 种类是: " + Puppy.getSpecies());
}
}
关于
this.的进一步解释:Java 优先查找局部变量,因此对于同名的
局部变量和成员变量,会优先认为是局部变量在 setter 方法中:由于 a 和 age 变量名不同,理论上 this 可以省略。
但如果参数名和实例变量名相同,就必须使用 this 来区分
在 getter 方法中: age 和 name 没有同名的
局部变量,所以默认查找的就是成员变量
6. 包(Package)
Java 提供**包(Package)**来管理类:
-
默认包(Unnamed Package):如果不声明
package,Java 会自 动使用默认包。 -
自定义包:
- 声明包:
package mypackage; - 导入包:
import mypackage.MyClass; - 使用类:
MyClass obj = new MyClass();
- 声明包:
示例:
package mypackage;
public class MyClass {
public void showMessage() {
System.out.println("这是我的包");
}
}
使用这个包
import mypackage.MyClass;
public class Test {
public static void main(String[] args) {
MyClass obj = new MyClass();
obj.showMessage();
}
}
7. Java 源文件声明规则
在 Java 开发中,源文件有以下规则:
- 一个源文件只能有一个
public类,类名必须与文件名相同。 - 可以有多个非
public类,但它们不能与文件名相同。 package语句必须放在文件的第一行(如果有)。import语句必须放在package之后,类定义之前。
示例:
package mypackage; // 必须放在首行
import java.util.*;
public class MyClass {
public void display() {
System.out.println("Hello, Java!");
}
}
(三)方法的特性
在上面的 类和对象 中,我们已经看到了 类中的方法是如何定义的。
方法还具有以下特 性
1. 参数按值传递
基本规则:
- Java 方法总是按值传递(通过参数的副本传递值)。
- 实参的值在方法调用中无法被改变。
示例:
public class TestPassByValue {
public static void main(String[] args) {
int num1 = 1;
int num2 = 2;
swap(num1, num2);
System.out.println("num1: " + num1 + ", num2: " + num2);
}
public static void swap(int n1, int n2) {
int temp = n1;
n1 = n2;
n2 = temp;
}
}
输出结果:
num1: 1, num2: 2
2. 方法的重载
定义:
- 同一个类中,可以定义多个名字相同但参数列表不同的方法。
- Java 编译器通过方法签名(方法名 + 参数列表)区分方法。
示例:
public static int max(int num1, int num2) {
return (num1 > num2) ? num1 : num2;
}
public static double max(double num1, double num2) {
return (num1 > num2) ? num1 : num2;
}
调用:
System.out.println(max(10.5, 15.0)); // 调用 double 类型版本
System.out.println(max(20, 30)); // 调用 int 类型版本
3. 可变参数(Varargs)
语法:
-
JDK 1.5 起支持在方法中声明可变参数:
public static void methodName(typeName... parameterName) {...} -
一个方法只能有一个可变参数,且必须是最后一个。
示例:
public static void printMax(double... numbers) {
if (numbers.length == 0) return;
double max = numbers[0];
for (double num : numbers) {
if (num > max) max = num;
}
System.out.println("The max value is " + max);
}
调用:
printMax(1, 2, 3, 4, 5);
printMax(new double[]{10, 20, 30});
输出:
The max value is 5
The max value is 30
4. 变量作用域
- 局部变量:声明于方法或代码块中,只在方法/块内可见。
- 参数变量:方法参数在整个方法中可见。
- 块内变量:变量可在声明的块内访问。

5. 命令行参数
main(String[] args) 中的 args 是用来给 命令行传递的参数数组。
示例:
public class CommandLine {
public static void main(String[] args) {
for (int i = 0; i < args.length; i++) {
System.out.println("args[" + i + "]: " + args[i]);
}
}
}
执行命令:
$ java CommandLine this is a test
输出:
args[0]: this
args[1]: is
args[2]: a
args[3]: test
(三)基本数据类型
Java 提供了两大数据类型:内置数据类型(基本数据类型)和 引用数据类型。
| 数据类型 | 说明 |
|---|---|
| 基本数据类型(Primitive Types) | 直接存储值,效率高 |
| 引用数据类型(Reference Types) | 存储对象的引用(如 String、数组、类等) |