Java编程技巧大全:从基础到高级的全面指南

第一部分:基础编程技巧

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代码。

关键要点总结:

  1. 遵循良好的编码规范和设计原则是编写高质量代码的基础
  2. 合理使用集合和流API可以大幅提升代码简洁性和可读性
  3. 并发编程需要特别注意线程安全和性能平衡
  4. 性能优化应从算法选择、数据结构和JVM特性等多方面考虑
  5. 及时采用现代Java特性可以简化代码并提高开发效率
  6. 良好的测试实践是保证代码质量的关键
评论 62
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百锦再@新空间

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值