Java 是一门面向对象的语言,"一切皆对象,一切皆类"。它采用"编译 + 解释"混合执行方式:源码先编译成字节码,再由 JVM 解释或即时编译(JIT)执行,与 Python 的"纯解释执行"、C 语言的"编译成机器码"都不相同。它与 Python 最大的区别在于:任何代码都必须写在类里,入口必须是 public static void main,类型必须显式声明。本文将用"水果"这一生活化主题贯穿始终,带你了解 Java 的核心基础语法,包括编译运行、基本类型、数组与集合、字符串、流程控制、方法与异常处理,以及 Java 的灵魂——面向对象(类与对象、封装、继承、接口、多态)。每部分都配有简短示例,适合从 Python 转过来的新手快速上手。
0. 程序结构与编译运行
Java 源文件名必须与公共类名一致(如 Hello.java 里必须是 public class Hello)。程序从 main 方法开始执行。就像一家水果店,Hello 是店名,main 是每天开店营业的入口。
// Hello.java
public class Hello {
public static void main(String[] args) {
System.out.println("Hello, 水果世界!");
}
}
编译运行:
javac Hello.java # 编译:生成 Hello.class 字节码(不是机器码)
java Hello # 运行:JVM 加载字节码,解释或 JIT 即时编译执行
与 Python 的对比:Python 是纯解释型语言,写脚本直接运行;Java 是"编译 + 解释"混合型——
javac先编译成平台无关的字节码,再由 JVM 解释/即时编译执行。字节码不依赖具体操作系统和 CPU,这就是"一次编写,到处运行"(Write Once, Run Anywhere)的原理。
1. 基本数据类型
Java 是强类型语言,有 8 种基本数据类型,变量必须先声明类型。就像水果店进货,必须先明确每种水果按什么单位计量。
public class Demo {
public static void main(String[] args) {
int apples = 42; // 整数 int:苹果个数
double grapeWeight = 3.14; // 双精度浮点数 double:葡萄重量(斤)
float unitPrice = 8.5f; // 单精度浮点数 float:单价(元/斤,加 f 后缀)
char grade = 'A'; // 单个字符 char:水果等级 A/B/C,用单引号
boolean isFresh = true; // 布尔值 boolean:水果是否新鲜,只能 true/false
long stockCount = 100000L; // 长整数 long:库存总量(要加 L 后缀)
System.out.println(apples); // 自动换行输出
System.out.println(grapeWeight);
System.out.printf("%.1f\n", unitPrice); // 格式化输出,保留一位
System.out.println(isFresh);
System.out.println(stockCount); // 库存总量输出
}
}
与 Python 的对比:Java 的基本类型是"值",不是对象;整数没有 Python 那样的任意大数,
int有范围限制(约 ±21亿),存不下很大的库存数要用long。
2. 数组与集合:水果篮与水果摊
Java 的数组长度固定,一旦创建不能改变,就像一排固定格数的水果架。要动态增删元素,需使用集合类 ArrayList,就像可以随时往里放水果的果篮。
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
// 数组:一排固定的水果架
String[] fruits = {"苹果", "葡萄", "香蕉", "橙子"};
System.out.println(fruits[0]); // 苹果
System.out.println(fruits.length); // 4,数组长度用 .length
// ArrayList:可以随意增减的果篮
ArrayList<String> basket = new ArrayList<>();
basket.add("葡萄"); // 放进去
basket.add("巨峰葡萄");
basket.add("苹果");
basket.remove(0); // 拿走第0个(葡萄)
System.out.println(basket.size()); // 2
System.out.println(basket.get(0)); // 巨峰葡萄
System.out.println(basket.contains("苹果")); // true
}
}
与 Python 的对比:
ArrayList用.add()添加、.get(i)取值、.size()求长度,没有 Python 的字典和集合内置类型(对应的是HashMap、HashSet)。
3. 字符串:String 类
Java 的字符串是 String 类对象,不可变(每次修改都会产生新对象)。就像水果的标签,贴上去就固定了。比较内容用 .equals() 而不是 ==。
public class Demo {
public static void main(String[] args) {
String fruit = "巨峰葡萄";
System.out.println(fruit.charAt(0)); // 巨,取第一个字符
System.out.println(fruit.length()); // 4,长度
System.out.println(fruit.substring(0, 2)); // 巨峰,切片 [0,2)
System.out.println(fruit.indexOf("葡萄")); // 2,查找子串位置
// 拼接字符串:+ 或 concat
String dish = "葡萄" + "汁";
System.out.println(dish); // 葡萄汁
// 比较内容必须用 equals,== 比较的是引用地址
String a = new String("苹果");
String b = new String("苹果");
System.out.println(a == b); // false(地址不同)
System.out.println(a.equals(b)); // true(内容相同)
}
}
与 Python 的对比:Java 字符串没有
s[-1]这样的负索引,也没有 Python 的in判断(要用.contains())。中文字符按字符计数,substring边界要小心。
4. 条件语句(if/else if/else)
根据条件执行不同代码块。就像判断一个水果是甜的、酸的还是烂的。条件必须放在括号里,代码块用 {} 包裹。
public class Demo {
public static void main(String[] args) {
int sweetness = 8; // 水果甜度 0~10
if (sweetness >= 8) {
System.out.println("很甜");
} else if (sweetness >= 5) {
System.out.println("一般甜");
} else {
System.out.println("偏酸");
}
}
}
Java 也支持 switch 语句,case 后要加 break 防止穿透。就像按水果种类给不同价格(下面的片段省去了类的 main 框架,完整可运行版本见配套代码文件夹):
String fruit = "葡萄";
switch (fruit) {
case "苹果": System.out.println("5元/斤"); break;
case "葡萄": System.out.println("8元/斤"); break;
default: System.out.println("时价");
}
5. 循环语句(for、while、for-each)
循环就是一遍遍处理,就像把果篮里的水果逐个清点、逐个称重。Java 有 for、while、do-while 三种循环,还有 Python 没有的 for-each 增强循环,专门用于遍历数组和集合。
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
// 经典 for 循环:从第1个数到第3个水果
for (int i = 1; i <= 3; i++) {
System.out.print("水果" + i + " ");
}
System.out.println();
// while 循环:一直试吃,直到满意
int satisfied = 0;
while (satisfied < 2) {
System.out.print("试吃 ");
satisfied++;
}
System.out.println();
// for-each 增强循环(类似 Python 的 for item in list)
String[] fruits = {"苹果", "葡萄", "香蕉"};
for (String f : fruits) {
System.out.print(f + " ");
}
System.out.println();
// 遍历 ArrayList 果篮
ArrayList<String> basket = new ArrayList<>();
basket.add("苹果");
basket.add("巨峰葡萄");
for (String f : basket) {
System.out.println(f);
}
}
}
6. 方法定义与调用
方法必须写在类里面,格式为"访问修饰符 + 返回类型 + 方法名(参数)"。没有返回值用 void。方法不能像 Python 那样单独存在。就像水果店的"称重"、"算钱"这些固定工序。
public class Demo {
// 返回 double,接收重量和单价,算出总价
static double calcPrice(double weight, double unitPrice) {
return weight * unitPrice;
}
// 没有返回值用 void,打印今日水果
static void printTodayFruits() {
System.out.println("今日水果:苹果、葡萄、巨峰葡萄");
}
public static void main(String[] args) {
printTodayFruits();
double total = calcPrice(2.5, 8.0); // 2.5斤葡萄,每斤8元
System.out.println(total); // 20.0
}
}
与 Python 的对比:Java 没有
def,且调用普通方法必须写返回类型;static表示静态方法,可直接通过类名调用,不需要先创建对象。
7. 方法参数:值传递与引用传递
Java 的基本类型参数按值传递(拷贝一份);对象参数按引用传递(传的是对象引用,方法内修改会影响原对象)。就像称重量时改的是"秤上的数字"(值拷贝),而往果篮里放水果改的是"果篮本身"(引用共享)。
import java.util.ArrayList;
public class Demo {
static void eatOne(int n) { // 基本类型:值传递,外部不变
n = n - 1;
}
static void addFruit(ArrayList<String> basket) { // 对象:引用传递
basket.add("香蕉");
}
public static void main(String[] args) {
int apples = 10;
eatOne(apples);
System.out.println(apples); // 10,没变
ArrayList<String> basket = new ArrayList<>();
addFruit(basket);
System.out.println(basket.size()); // 1,变了(果篮里有了香蕉)
}
}
注意:Java 没有 C 语言的指针语法,没有
*、&运算符;所有对象都用"引用"操作。
8. 返回值与方法重载
方法通过 return 返回结果,返回类型必须与方法声明一致。一个方法只能返回一个值。Java 支持方法重载:方法名相同、参数列表不同(个数或类型不同)可以共存,调用时按参数自动匹配。就像"榨果汁":给苹果榨出苹果汁,给橙子榨出橙汁,同一个词、不同输入。
public class Demo {
// 两个方法同名,参数类型不同 —— 方法重载
static String makeJuice(String fruit) {
return fruit + "汁";
}
static String makeJuice(String fruit1, String fruit2) {
return fruit1 + fruit2 + "混合汁";
}
public static void main(String[] args) {
System.out.println(makeJuice("葡萄")); // 葡萄汁
System.out.println(makeJuice("苹果", "香蕉")); // 苹果香蕉混合汁
}
}
与 Python 的对比:Python 可以用默认参数实现类似效果,Java 没有默认参数,但可以用重载弥补;Java 也没有 Python 那种"返回多个值(元组)"的写法。
9. 包与导入
Java 用 import 引入其他类(相当于 Python 的 from ... import ...),用 package 声明包(相当于 Python 的模块目录)。java.util、java.lang 等是 JDK 自带的标准包。就像水果店里各种固定摆放的货架区域。
import java.util.Scanner; // 导入 java.util 包里的 Scanner 类
import java.util.*; // 导入整个包(不推荐,太宽泛)
public class Demo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请问你要买什么水果?");
String fruit = scanner.next();
System.out.println("你选择了:" + fruit);
scanner.close();
}
}
与 Python 的对比:Java 的
java.lang包(String、Math 等)默认自动导入,其余包需要import。自定义类放在同一个包(目录)里可直接使用,无需 import。
10. 异常处理(try/catch/finally)
Java 用 try...catch...finally 捕获异常,与 Python 的 try...except...finally 非常相似。Java 强制要求处理某些"受检异常"(编译期必须 try/catch 或声明 throws)。就像水果店分装水果,发现"分到一半果篮没了"就停下处理。
public class Demo {
public static void main(String[] args) {
try {
int apples = 10;
int baskets = 0; // 果篮数量为0
int perBasket = apples / baskets; // 触发 ArithmeticException
System.out.println(perBasket);
} catch (ArithmeticException e) { // 捕获算术异常
System.out.println("果篮不能为0!");
} finally {
System.out.println("无论是否异常,分装流程都会结束");
}
}
}
多个异常可以写多个 catch,也可以合并写:catch (IOException | SQLException e)。还可以用 throw 主动抛出异常、用 throws 声明方法可能抛出的异常。
与 Python 的对比:Python 是
except ZeroDivisionError,Java 是catch (ArithmeticException e);Java 的异常要处理或声明,Python 相对宽松。
11. 面向对象:类与对象
面向对象是 Java 的灵魂。类(class)是创建对象的模板,对象(object)是根据模板创建出来的实例。就像"水果"是一个抽象概念(类),而桌上这串"巨峰葡萄"是一个具体对象。定义类用 class 关键字,new 创建对象,. 调用对象的方法。
public class Demo {
public static void main(String[] args) {
// new 创建对象:两个不同的葡萄对象
Grape grape1 = new Grape("巨峰葡萄", 20);
Grape grape2 = new Grape("阳光玫瑰", 35);
// 调用对象的方法
grape1.describe();
System.out.println(grape2.getPrice());
}
}
// 定义 Grape 类
class Grape {
private String variety; // 成员变量(属性):品种
private int price; // 每斤价格
// 构造方法:与类同名,创建对象时自动调用
public Grape(String variety, int price) {
this.variety = variety;
this.price = price;
}
public void describe() {
System.out.println(this.variety + ",每斤" + this.price + "元");
}
public int getPrice() {
return this.price;
}
}
与 Python 的对比:Python 用
__init__作构造方法、self表示对象自身;Java 用与类同名的构造方法、this表示对象自身。Python 的def method(self, ...)对应 Java 的public void method(...)。
12. 封装(Encapsulation)
封装是指把数据(成员变量)设为私有,通过公开的方法(getter/setter)来访问,从而保护数据不被随意修改。Java 用 private 关键字实现封装。就像水果的"生产日期"不能让人随便改,只能通过店铺登记。
public class Demo {
public static void main(String[] args) {
Fruit orange = new Fruit("橙子", 10);
orange.raisePrice(2); // 涨价2元
System.out.println(orange.getPrice()); // 12
System.out.println(orange.setDiscount(-5)); // false,非法折扣
System.out.println(orange.getPrice()); // 12,价格未被破坏
}
}
class Fruit {
private String name; // 私有属性,外部不能直接访问
private int price;
public Fruit(String name, int price) {
this.name = name;
this.price = price;
}
// getter:获取私有属性
public int getPrice() {
return this.price;
}
// 封装业务逻辑:涨价、打折都通过公开方法完成,并做合法性校验
public void raisePrice(int amount) {
if (amount > 0) {
this.price += amount;
}
}
public boolean setDiscount(int percent) {
if (percent >= 0 && percent <= 100) {
this.price = this.price * (100 - percent) / 100;
return true;
}
return false; // 非法折扣(负数或超过100)直接拒绝
}
}
与 Python 的对比:Python 靠
_name约定"内部属性",但实际仍可访问;Java 用private强制禁止外部直接访问,必须走 getter/setter,保护更彻底。
13. 继承(Inheritance)与多态(Polymorphism)
继承用 extends 让子类复用父类的属性和方法,并可重写(@Override)父类方法。多态指同一个父类类型的引用指向不同子类对象时,调用同名方法表现出不同行为。
用"水果 → 葡萄 → 巨峰葡萄"这条食物链理解最直观:水果 是父类(所有水果都有味道),葡萄 是水果的子类(有葡萄特有风味),巨峰葡萄 又是葡萄的子类(更甜更大)。
public class Demo {
public static void main(String[] args) {
// 多态:父类引用指向子类对象
Fruit f1 = new Grape();
Fruit f2 = new KyohoGrape();
f1.taste(); // 葡萄:酸甜多汁
f2.taste(); // 巨峰葡萄:个大、更甜
}
}
// 父类:水果
class Fruit {
public void taste() {
System.out.println("水果的味道");
}
}
// 子类:葡萄,继承水果
class Grape extends Fruit {
@Override
public void taste() {
System.out.println("葡萄:酸甜多汁");
}
}
// 孙类:巨峰葡萄,继承葡萄
class KyohoGrape extends Grape {
@Override
public void taste() {
System.out.println("巨峰葡萄:个大、更甜");
}
}
与 Python 的对比:Python 用
class Grape(Fruit)继承,Java 用class Grape extends Fruit;Python 重写方法不需要修饰符,Java 可以加@Override注解让编译器帮你检查。多层继承(水果→葡萄→巨峰葡萄)两种语言都支持。
14. 接口(Interface)
接口定义了一组方法"规范"(只声明、不实现),实现类用 implements 必须实现接口里所有方法。接口用于约定能力,实现同一接口的类可以互换使用。就像"可食用"是个约定:凡是声明"可食用"的水果,都必须能回答"怎么吃"。
public class Demo {
public static void main(String[] args) {
// 用接口类型引用实现类对象
Edible e1 = new Grape();
e1.howToEat(); // 葡萄:洗净直接吃
}
}
// 接口:只声明方法,不实现
interface Edible {
void howToEat();
}
// 实现接口:必须实现 howToEat 方法
class Grape implements Edible {
@Override
public void howToEat() {
System.out.println("葡萄:洗净直接吃");
}
}
与 Python 的对比:Python 没有
interface关键字,靠鸭子类型(有方法就能调);Java 用接口强制实现类提供约定方法,是"面向接口编程"的基础。
掌握以上基础语法与面向对象核心概念,你已经能读懂并编写 Java 的日常小程序了!不妨动手做一个"水果摊记账小程序"练练手。下一步建议深入学习集合框架(HashMap、HashSet、泛型)、Lambda 表达式和流式处理(Stream API),以及多线程与网络编程。Java 是大型企业级应用的绝对主力,学好它的类型系统与面向对象思想,会为你打开一片广阔的工程世界。