第一部分:基础编程技巧
1.1 代码组织与结构
1.1.1 包结构设计
// 推荐的项目包结构
com.company.project
├── domain // 领域模型
├── repository // 数据访问层
├── service // 业务逻辑层
├── web // 控制器层
├── config // 配置类
├── exception // 自定义异常
└── util // 工具类
1.1.2 类设计原则
- 单一职责原则(SRP):每个类只负责一个功能
- 开闭原则(OCP):对扩展开放,对修改关闭
- 里氏替换原则(LSP):子类可以替换父类
- 接口隔离原则(ISP):客户端不应依赖不需要的接口
- 依赖倒置原则(DIP):依赖抽象而非具体实现
1.2 命名规范
1.2.1 通用命名规则
// 类名:大驼峰
public class UserService {}
// 方法名:小驼峰
public void getUserById() {}
// 常量:全大写加下划线
public static final int MAX_COUNT = 100;
// 变量:小驼峰
String userName = "John";
1.2.2 特定场景命名
// 布尔变量/方法使用is/has/can等前缀
boolean isActive;
boolean hasPermission();
boolean canExecute();
// 集合类变量使用复数形式
List<User> users = new ArrayList<>();
// 测试方法名应表达测试意图
@Test
void shouldThrowExceptionWhenInputIsNegative() {}
1.3 异常处理
1.3.1 异常处理最佳实践
try {
// 可能抛出异常的代码
processFile(file);
} catch (FileNotFoundException e) {
// 处理特定异常
logger.error("File not found: " + file.getName(), e);
throw new BusinessException("File not found", e);
} catch (IOException e) {
// 处理更通用的异常
logger.error("IO error processing file", e);
throw new BusinessException("IO error", e);
} finally {
// 清理资源
closeResources();
}
1.3.2 自定义异常设计
public class BusinessException extends RuntimeException {
private final ErrorCode errorCode;
public BusinessException(ErrorCode errorCode) {
super(errorCode.getMessage());
this.errorCode = errorCode;
}
public BusinessException(ErrorCode errorCode, Throwable cause) {
super(errorCode.getMessage(), cause);
this.errorCode = errorCode;
}
public ErrorCode getErrorCode() {
return errorCode;
}
}
// 使用枚举定义错误码
public enum ErrorCode {
USER_NOT_FOUND(1001, "User not found"),
INVALID_INPUT(1002, "Invalid input");
private final int code;
private final String message;
// 构造函数和getter
}
第二部分:集合与流处理技巧
2.1 集合操作
2.1.1 集合初始化
// 使用工厂方法创建集合
List<String> names = List.of("Alice", "Bob", "Charlie"); // 不可变
Set<Integer> numbers = Set.of(1, 2, 3);
Map<String, Integer> scores = Map.of("Alice", 90, "Bob", 85);
// 创建空集合
List<String> emptyList = Collections.emptyList();
Map<String, String> emptyMap = Collections.emptyMap();
// 创建单元素集合
List<String> singletonList = Collections.singletonList("Single");
2.1.2 集合操作技巧
// 列表分割
List<List<Integer>> partitions = ListUtils.partition(bigList, 100); // Apache Commons
// 集合过滤
List<User> activeUsers = users.stream()
.filter(User::isActive)
.collect(Collectors.toList());
// 集合转换
Map<Long, User> userMap = users.stream()
.collect(Collectors.toMap(User::getId, Function.identity()));
// 集合排序
users.sort(Comparator.comparing(User::getName)
.thenComparing(User::getAge));
2.2 Stream API高级用法
2.2.1 流处理模式
// 分组
Map<Department, List<Employee>> byDept = employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment));
// 分区
Map<Boolean, List<Employee>> partitioned = employees.stream()
.collect(Collectors.partitioningBy(e -> e.getSalary() > 5000));
// 统计
IntSummaryStatistics stats = employees.stream()
.mapToInt(Employee::getSalary)
.summaryStatistics();
// 扁平化处理
List<String> allTags = articles.stream()
.flatMap(article -> article.getTags().stream())
.distinct()
.collect(Collectors.toList());
2.2.2 自定义收集器
// 实现一个连接字符串的自定义收集器
Collector<String, StringBuilder, String> stringCollector =
Collector.of(
StringBuilder::new, // supplier
StringBuilder::append, // accumulator
StringBuilder::append, // combiner
StringBuilder::toString // finisher
);
String result = Stream.of("a", "b", "c")
.collect(stringCollector);
第三部分:并发编程技巧
3.1 线程管理
3.1.1 线程池最佳实践
// 创建线程池
ExecutorService executor = Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors(),
new ThreadFactory() {
private final AtomicInteger counter = new AtomicInteger(1);
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "worker-" + counter.getAndIncrement());
}
}
);
// 提交任务
Future<String> future = executor.submit(() -> {
// 长时间运行的任务
return processData(data);
});
// 优雅关闭
executor.shutdown();
try {
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
executor.shutdownNow();
}
} catch (InterruptedException e) {
executor.shutdownNow();
Thread.currentThread().interrupt();
}
3.1.2 CompletableFuture使用技巧
// 链式异步调用
CompletableFuture.supplyAsync(() -> fetchUser(userId), executor)
.thenApplyAsync(user -> enrichUser(user), executor)
.thenApplyAsync(enrichedUser -> saveUser(enrichedUser), executor)
.exceptionally(ex -> {
logger.error("Error processing user", ex);
return null;
});
// 组合多个Future
CompletableFuture<User> userFuture = getUserAsync(userId);
CompletableFuture<Order> orderFuture = getOrdersAsync(userId);
userFuture.thenCombine(orderFuture, (user, orders) -> {
user.setOrders(orders);
return user;
});
// 并行执行多个任务
CompletableFuture<Void> allFutures = CompletableFuture.allOf(
task1, task2, task3
);
allFutures.thenRun(() -> {
// 所有任务完成后的处理
});
3.2 并发工具类
3.2.1 并发集合使用
// 线程安全Map
ConcurrentMap<String, User> userCache = new ConcurrentHashMap<>();
// 原子操作
userCache.computeIfAbsent(userId, id -> loadUserFromDB(id));
// 阻塞队列
BlockingQueue<Order> orderQueue = new LinkedBlockingQueue<>(1000);
// 生产者
orderQueue.put(newOrder);
// 消费者
Order order = orderQueue.take();
processOrder(order);
// 计数器
LongAdder totalRequests = new LongAdder();
totalRequests.increment();
long count = totalRequests.sum();
3.2.2 同步工具
// 信号量控制资源访问
Semaphore dbConnections = new Semaphore(10);
try {
dbConnections.acquire();
// 使用数据库连接
} finally {
dbConnections.release();
}
// 倒计时门闩
CountDownLatch latch = new CountDownLatch(3);
// 多个线程中
doWork();
latch.countDown();
// 主线程等待
latch.await();
// 循环屏障
CyclicBarrier barrier = new CyclicBarrier(3, () -> {
// 所有线程到达后执行
});
// 工作线程中
doWork();
barrier.await();
第四部分:性能优化技巧
4.1 JVM调优
4.1.1 内存管理
// 对象重用池
public class ObjectPool<T> {
private final Supplier<T> creator;
private final Queue<T> pool = new ConcurrentLinkedQueue<>();
public ObjectPool(Supplier<T> creator) {
this.creator = creator;
}
public T borrow() {
T obj = pool.poll();
return obj != null ? obj : creator.get();
}
public void release(T obj) {
pool.offer(obj);
}
}
// 使用示例
ObjectPool<StringBuilder> pool = new ObjectPool<>(StringBuilder::new);
StringBuilder sb = pool.borrow();
try {
// 使用StringBuilder
} finally {
pool.release(sb);
}
4.1.2 垃圾回收优化
// 大对象分配优化
// 避免:
byte[] largeBuffer = new byte[10 * 1024 * 1024]; // 10MB
// 改为:
List<byte[]> chunks = new ArrayList<>();
for (int i = 0; i < 10; i++) {
chunks.add(new byte[1024 * 1024]); // 1MB chunks
}
// 对象生命周期管理
try (ReusableObject obj = pool.acquire()) {
// 使用对象
} // 自动释放回池中
4.2 代码级优化
4.2.1 字符串处理
// 字符串拼接优化
// 避免:
String result = "";
for (String part : parts) {
result += part; // 每次循环创建新对象
}
// 使用StringBuilder:
StringBuilder builder = new StringBuilder();
for (String part : parts) {
builder.append(part);
}
String result = builder.toString();
// Java 8+使用String.join:
String result = String.join("", parts);
// 字符串常量池利用
String s1 = "hello"; // 使用常量池
String s2 = new String("hello"); // 创建新对象
String s3 = s2.intern(); // 放入常量池并返回引用
4.2.2 集合优化
// 集合容量初始化
// 避免:
List<User> users = new ArrayList<>(); // 默认容量10
for (int i = 0; i < 1000; i++) {
users.add(new User()); // 多次扩容
}
// 优化:
List<User> users = new ArrayList<>(1000); // 指定初始容量
// Map优化
Map<String, User> userMap = new HashMap<>(1000, 0.75f); // 指定初始容量和负载因子
// 枚举集合优化
EnumMap<DayOfWeek, String> activityMap = new EnumMap<>(DayOfWeek.class);
EnumSet<DayOfWeek> weekend = EnumSet.of(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY);
第五部分:现代Java特性应用
5.1 记录类(Record)
5.1.1 Record使用技巧
// 定义Record
public record User(Long id, String name, int age) {
// 可以添加紧凑构造函数
public User {
if (age < 0) {
throw new IllegalArgumentException("Age cannot be negative");
}
name = name.trim();
}
// 可以添加方法
public boolean isAdult() {
return age >= 18;
}
}
// 使用Record
User user = new User(1L, "Alice", 25);
System.out.println(user.name()); // 自动生成的访问器
System.out.println(user); // 自动生成的toString()
// 与旧代码互操作
public class UserService {
public static User fromEntity(UserEntity entity) {
return new User(entity.getId(), entity.getName(), entity.getAge());
}
}
5.2 模式匹配
5.2.1 instanceof模式匹配
// 传统方式
if (obj instanceof String) {
String s = (String) obj;
System.out.println(s.length());
}
// Java 16+模式匹配
if (obj instanceof String s) {
System.out.println(s.length());
}
// 在switch中使用
switch (obj) {
case String s -> System.out.println("String: " + s);
case Integer i -> System.out.println("Integer: " + i);
case null, default -> System.out.println("Other type");
}
5.2.2 记录模式匹配
// Java 19+预览功能
public void processShape(Shape shape) {
if (shape instanceof Circle(Color c, Point center, double radius)) {
System.out.println("Circle with color " + c + " and radius " + radius);
} else if (shape instanceof Rectangle(Color c, Point topLeft, Point bottomRight)) {
System.out.println("Rectangle with color " + c);
}
}
5.3 虚拟线程(Loom项目)
5.3.1 虚拟线程使用
// 创建虚拟线程
Thread virtualThread = Thread.startVirtualThread(() -> {
System.out.println("Running in virtual thread");
});
// 使用ExecutorService
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, 10_000).forEach(i -> {
executor.submit(() -> {
Thread.sleep(Duration.ofSeconds(1));
return i;
});
});
} // executor.close()自动调用
// 与传统代码集成
Future<String> future = CompletableFuture.supplyAsync(() -> {
// 在虚拟线程中运行
return fetchData();
}, Executors.newVirtualThreadPerTaskExecutor());
第六部分:设计模式与架构
6.1 常用设计模式实现
6.1.1 策略模式
// 策略接口
public interface DiscountStrategy {
BigDecimal applyDiscount(BigDecimal amount);
}
// 具体策略
public class NoDiscount implements DiscountStrategy {
@Override
public BigDecimal applyDiscount(BigDecimal amount) {
return amount;
}
}
public class PercentageDiscount implements DiscountStrategy {
private final BigDecimal percentage;
public PercentageDiscount(BigDecimal percentage) {
this.percentage = percentage;
}
@Override
public BigDecimal applyDiscount(BigDecimal amount) {
return amount.multiply(BigDecimal.ONE.subtract(percentage));
}
}
// 上下文
public class Order {
private DiscountStrategy discountStrategy = new NoDiscount();
public void setDiscountStrategy(DiscountStrategy strategy) {
this.discountStrategy = strategy;
}
public BigDecimal calculateTotal(BigDecimal subtotal) {
return discountStrategy.applyDiscount(subtotal);
}
}
6.1.2 装饰器模式
// 基础接口
public interface Coffee {
String getDescription();
BigDecimal getCost();
}
// 具体组件
public class SimpleCoffee implements Coffee {
@Override
public String getDescription() {
return "Simple coffee";
}
@Override
public BigDecimal getCost() {
return new BigDecimal("1.00");
}
}
// 装饰器基类
public abstract class CoffeeDecorator implements Coffee {
protected final Coffee decoratedCoffee;
public CoffeeDecorator(Coffee coffee) {
this.decoratedCoffee = coffee;
}
@Override
public String getDescription() {
return decoratedCoffee.getDescription();
}
@Override
public BigDecimal getCost() {
return decoratedCoffee.getCost();
}
}
// 具体装饰器
public class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return decoratedCoffee.getDescription() + ", with milk";
}
@Override
public BigDecimal getCost() {
return decoratedCoffee.getCost().add(new BigDecimal("0.50"));
}
}
6.2 模块化设计
6.2.1 Java模块系统
// module-info.java
module com.example.myapp {
requires java.base;
requires java.sql;
requires transitive com.example.common;
exports com.example.myapp.api;
exports com.example.myapp.internal to com.example.test;
opens com.example.myapp.model to spring.core;
uses com.example.spi.ServiceProvider;
provides com.example.spi.ServiceProvider
with com.example.myapp.MyServiceProvider;
}
6.2.2 分层架构
// 典型的分层架构
// 表示层
@RestController
@RequestMapping("/users")
public class UserController {
private final UserService userService;
@GetMapping("/{id}")
public ResponseEntity<UserDto> getUser(@PathVariable Long id) {
return ResponseEntity.ok(userService.getUserById(id));
}
}
// 服务层
@Service
@Transactional
public class UserService {
private final UserRepository userRepository;
public UserDto getUserById(Long id) {
return userRepository.findById(id)
.map(this::toDto)
.orElseThrow(() -> new UserNotFoundException(id));
}
private UserDto toDto(User user) {
// 转换逻辑
}
}
// 数据访问层
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByEmail(String email);
}
// 领域模型
@Entity
public class User {
@Id @GeneratedValue
private Long id;
private String name;
private String email;
// 其他字段和方法
}
第七部分:测试与调试
7.1 单元测试技巧
7.1.1 JUnit 5高级用法
@DisplayName("User Service Tests")
class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
@Test
@DisplayName("Should find user by ID")
void shouldFindUserById() {
// Given
User user = new User(1L, "Alice");
when(userRepository.findById(1L)).thenReturn(Optional.of(user));
// When
UserDto result = userService.getUserById(1L);
// Then
assertNotNull(result);
assertEquals("Alice", result.getName());
verify(userRepository).findById(1L);
}
@ParameterizedTest
@CsvSource({
"1, Alice",
"2, Bob"
})
void shouldFindUserByIdParameterized(Long id, String name) {
// Given
User user = new User(id, name);
when(userRepository.findById(id)).thenReturn(Optional.of(user));
// When/Then
assertEquals(name, userService.getUserById(id).getName());
}
}
7.1.2 测试替身策略
// 使用Mockito创建测试替身
@Test
void testWithMocks() {
// 创建mock
PaymentGateway gateway = mock(PaymentGateway.class);
// 设置预期行为
when(gateway.processPayment(any(BigDecimal.class)))
.thenReturn(PAYMENT_SUCCESS);
// 使用mock
PaymentService service = new PaymentService(gateway);
PaymentResult result = service.chargeCustomer(new BigDecimal("100.00"));
// 验证
assertEquals(PAYMENT_SUCCESS, result);
verify(gateway).processPayment(new BigDecimal("100.00"));
}
// 使用内存数据库测试Repository
@DataJpaTest
class UserRepositoryTest {
@Autowired
private TestEntityManager entityManager;
@Autowired
private UserRepository userRepository;
@Test
void shouldFindByEmail() {
// Given
User user = new User("test@example.com", "Test User");
entityManager.persist(user);
// When
Optional<User> found = userRepository.findByEmail("test@example.com");
// Then
assertTrue(found.isPresent());
assertEquals("Test User", found.get().getName());
}
}
7.2 调试技巧
7.2.1 条件断点
// 在IDE中设置条件断点
for (User user : users) {
// 设置条件断点: user.getName().equals("Alice")
processUser(user);
}
7.2.2 日志调试
// 使用SLF4J进行日志记录
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class UserProcessor {
private static final Logger logger = LoggerFactory.getLogger(UserProcessor.class);
public void processUsers(List<User> users) {
logger.debug("Starting to process {} users", users.size());
try {
for (User user : users) {
logger.trace("Processing user: {}", user);
// 处理逻辑
}
} catch (Exception e) {
logger.error("Error processing users", e);
throw new ProcessingException("User processing failed", e);
}
logger.info("Successfully processed {} users", users.size());
}
}
结语
本文全面介绍了Java编程中的各种技巧,从基础编码规范到高级并发处理,从性能优化到现代Java特性应用。掌握这些技巧可以帮助开发者编写出更高效、更健壮、更易维护的Java代码。
关键要点总结:
- 遵循良好的编码规范和设计原则是编写高质量代码的基础
- 合理使用集合和流API可以大幅提升代码简洁性和可读性
- 并发编程需要特别注意线程安全和性能平衡
- 性能优化应从算法选择、数据结构和JVM特性等多方面考虑
- 及时采用现代Java特性可以简化代码并提高开发效率
- 良好的测试实践是保证代码质量的关键