Java基础四:Java命名规则与修饰符
Java命名规则
变量名应该具有清晰的含义,能够准确地反映变量的用途。避免使用单个字符或无意义的缩写。
-
驼峰命名法: 在变量名中使用驼峰命名法,即将每个单词的首字母大写,除了第一个单词外,其余单词的首字母都采用大写形式。例如:
myVariableName。 -
避免关键字: 不要使用 Java 关键字(例如,class、int、boolean等)作为变量名。
-
区分大小写: Java 是大小写敏感的,因此变量名中的大小写字母被视为不同的符号。例如,
myVariable和myvariable是两个不同的变量。 -
不以数字开头: 变量名不能以数字开头,但可以包含数字。
-
遵循命名约定: 对于不同类型的变量(局部变量、实例变量、静态变量等),可以采用不同的命名约定,例如使用前缀或后缀来区分。
局部变量
- 使用驼峰命名法。
- 应该以小写字母开头。
- 变量名应该是描述性的,能够清晰地表示其用途。
int myLocalVariable;
实例变量(成员变量)
- 使用驼峰命名法。
- 应该以小写字母开头。
- 变量名应该是描述性的,能够清晰地表示其用途。
private int myInstanceVariable;
静态变量(类变量)
- 使用驼峰命名法,应该以小写字母开头。
- 通常也可以使用大写蛇形命名法,全大写字母,单词之间用下划线分隔。
- 变量名应该是描述性的,能够清晰地表示其用途。
// 使用驼峰命名法
public static int myStaticVariable;
// 使用大写蛇形命名法
public static final int MAX_SIZE = 100;
常量
- 使用全大写字母,单词之间用下划线分隔。
- 常量通常使用
final修饰。
public static final double PI = 3.14;
参数
- 使用驼峰命名法。
- 应该以小写字母开头。
- 参数名应该是描述性的,能够清晰地表示其用途。
public void myMethod(int myParameter) {
// 方法体
}
类名
- 使用驼峰命名法。
- 应该以大写字母开头。
- 类名应该是描述性的,能够清晰地表示其用途。
public class MyClass {
// 类的成员和方法
}
修饰符
Java语言提供了很多修饰符,主要分为以下两类:访问修饰符,非访问修饰符
访问修饰符:
Java中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。Java 支持 4 种不同的访问权限。
1. private(私有)
被private修饰的成员只能在其所在的类内部被访问,对外部完全隐藏。这是限制最严格的修饰符。
使用对象:成员变量、方法、构造器、注意:不能修饰类(外部类)。
public class Person {
private String name; // 私有变量
private void secretMethod() { ... } // 私有方法
public String getName() { return name; } // 公共访问入口
}
2. default(包级私有)
当成员没有显式指定任何访问修饰符时,它采用默认访问级别。该成员可以被同一个包内的所有类访问,但对包外的类(即使是子类)不可见。
使用对象:类、接口、变量、方法。
// 文件路径: com/example/utils/Helper.java
package com.example.utils;
class Helper { // 默认访问权限,只能被同包类访问
void doHelp() { ... }
}
// 文件路径: com/example/utils/Main.java
package com.example.utils;
public class Main {
public static void main(String[] args) {
Helper h = new Helper(); // 同一包内,可以访问
h.doHelp();
}
}
3. protected(受保护)
被protected修饰的成员可以被同一个包内的所有类以及不同包中的子类访问。它体现了继承中的访问特性。
使用对象:变量、方法。 注意:不能修饰类(外部类)。
public class Animal {
protected void makeSound() { System.out.println("Some sound"); }
}
public class Dog extends Animal {
@Override
protected void makeSound() { System.out.println("Bark"); }
}
4.public(公共的)
被声明为public的元素可以被任何其他类访问,无论是否在同一包中。
使用对象:类、接口、变量、方法。
public class MathUtils {
public static final double PI = 3.14159;
public int add(int a, int b) { return a + b; }
}
非访问修饰符
1.static
表示成员属于类本身,而不是某个对象实例。静态变量在内存中只有一份拷贝,静态方法不能直接访问实例成员。
使用场景:工具类的方法,常量,单例模式中的静态实例,静态代码块用于类初始化
public class Counter {
private static int count = 0;
public static void increment() { count++; }
}
2.final
表示“不可变”。
修饰变量:变量值一旦赋值不可修改(基本类型值不变,引用类型指向的对象不变)。
修饰方法:方法不能被重写。
修饰类:类不能被继承。
public final class Constants {
public static final int MAX_SIZE = 100;
public final void print() { System.out.println("Fixed"); }
}
3.abstract
修饰类或方法。
抽象类:不能实例化,可以包含抽象方法和具体方法。
抽象方法:只有声明,没有实现,必须由字类实现。
public abstract class Shape {
public abstract double area();
public void display() { System.out.println("This is a shape"); }
}
public class Circle extends Shape {
private double radius;
@Override public double area() { return Math.PI * radius * radius; }
}
4.synchronized
用于多线程环境,确保同一时刻只有一个线程可以执行被修饰的方法或代码块。基于对象锁(实例方法)或类锁(静态方法)实现线程同步。
使用场景:线程安全的计数器、共享资源访问控制,保证数据一致性,如银行转账、库存扣减,多线程环境下对共享变量的复合操作
public class SafeCounter {
private int count = 0;
public synchronized void increment() { // 同步实例方法,锁当前对象
count++;
}
public synchronized int getCount() { // 同步读取,保证可见性
return count;
}
// 也可以使用同步代码块,更精细控制
public void decrement() {
synchronized (this) {
count--;
}
}
}
5.volatile
保证变量的可见性,即一个线程修改了volatile变量后,其他线程能立即看到最新值。同时禁止指令重排序,防止CPU或编译器对指令进行优化导致的问题。
使用场景:状态标记在多线程间共享,用于控制线程启停,双重检查锁单例模式中防止指令重排,
替代简单的同步场景,当只需要保证可见性而不需要原子性时
public class Worker {
private volatile boolean running = true; // 线程可见的状态标志
public void run() {
while (running) {
// 执行任务
}
System.out.println("Worker stopped.");
}
public void stop() {
running = false; // 修改对其他线程立即可见
}
public static void main(String[] args) throws InterruptedException {
Worker worker = new Worker();
new Thread(worker::run).start();
Thread.sleep(1000);
worker.stop(); // 停止线程
}
}
6.transient
在对象序列化时,被transient修饰的字段不会被持久化(即忽略该字段)。当对象被反序列化时,该字段会被初始化为默认值(如null、0)。
使用场景:敏感信息(如密码、密钥)不想被序列化保存到文件中,字段的值可以从其他数据计算得出,无需存储(如缓存数据、派生属性),对象中包含不可序列化的引用(如Thread、Socket),需要标记为transient避免序列化异常
import java.io.*;
public class User implements Serializable {
private String username;
private transient String password; // 密码不参与序列化
public User(String username, String password) {
this.username = username;
this.password = password;
}
@Override
public String toString() {
return "User{username='" + username + "', password='" + password + "'}";
}
public static void main(String[] args) throws Exception {
User user = new User("alice", "secret123");
// 序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.ser"));
oos.writeObject(user);
oos.close();
// 反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.ser"));
User deserializedUser = (User) ois.readObject();
ois.close();
System.out.println("Original: " + user);
System.out.println("Deserialized: " + deserializedUser); // password 为 null
}
}
更多推荐


所有评论(0)