最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot + MQTT實(shí)現(xiàn)取貨就走的智能售貨柜系統(tǒng)完整流程

 更新時(shí)間:2026年03月10日 10:11:23   作者:程序員大華  
本文介紹了一種智能售貨柜的工作原理和實(shí)現(xiàn)流程,該系統(tǒng)通過多傳感器數(shù)據(jù)融合、實(shí)時(shí)視頻流處理和異步處理,提供無感購物體驗(yàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧

大家好,我是大華。昨天在辦公樓底下,我用了一下那種開門拿貨,關(guān)門自動(dòng)扣費(fèi)的智能售貨柜,真挺方便的。

其實(shí)這種售貨柜并不少見,很多無人售貨店、地鐵站和景區(qū)都能經(jīng)常看懂。

那這種流程是怎么實(shí)現(xiàn)的呢?下面我們來分析一下整個(gè)實(shí)現(xiàn)的流程。

場(chǎng)景:

  1. 你用微信掃描售貨柜上的二維碼
  2. 柜門咔嚓一聲自動(dòng)打開
  3. 你拿出想要的商品,同時(shí)可以隨意更換
  4. 關(guān)上柜門,然后手機(jī)自動(dòng)收到扣款通知
  5. 整個(gè)過程中無需任何額外操作

核心技術(shù)棧(Spingboot)

技術(shù)組件作用
Spring Boot后端主框架
Redis高速緩存
MQTT物聯(lián)網(wǎng)通信協(xié)議
MySQL關(guān)系型數(shù)據(jù)庫
消息隊(duì)列異步任務(wù)處理
計(jì)算機(jī)視覺拍攝商品識(shí)別

完整技術(shù)流程詳解

第一階段:掃碼開門(身份驗(yàn)證與初始化)

用戶動(dòng)作:微信掃碼 → 授權(quán) → 柜門打開

后臺(tái)流程

  1. 身份認(rèn)證:驗(yàn)證微信賬號(hào)的合法性
  2. 設(shè)備狀態(tài)檢查:確認(rèn)售貨柜是否可用
  3. 創(chuàng)建會(huì)話:在Redis中建立臨時(shí)購物車
  4. 數(shù)據(jù)采集:拍攝貨架初始照片,記錄傳感器數(shù)據(jù)
  5. 開門指令:通過MQTT協(xié)議發(fā)送開門命令

技術(shù)要點(diǎn)

  • 使用Redis存儲(chǔ)臨時(shí)會(huì)話,讀寫速度達(dá)到微秒級(jí)
  • MQTT協(xié)議專為物聯(lián)網(wǎng)設(shè)計(jì),低功耗、高可靠
  • 初始快照為后續(xù)對(duì)比提供基準(zhǔn)數(shù)據(jù)

第二階段:自由選購(實(shí)時(shí)事件追蹤)

用戶動(dòng)作:拿取商品 → 可能更換 → 繼續(xù)選購

系統(tǒng)監(jiān)控

  1. 視覺追蹤:攝像頭實(shí)時(shí)識(shí)別手部動(dòng)作和商品變化
  2. 重量感應(yīng):每個(gè)貨道的傳感器監(jiān)測(cè)重量變化
  3. 事件上報(bào):實(shí)時(shí)將"拿取/放回"動(dòng)作發(fā)送到后臺(tái)
  4. 實(shí)時(shí)記錄:在Redis中更新購物車狀態(tài)

技術(shù)難點(diǎn)突破

  • 實(shí)時(shí)視頻流處理,延遲控制在100ms以內(nèi)
  • 多傳感器數(shù)據(jù)融合,提高識(shí)別準(zhǔn)確率
  • 高并發(fā)事件處理,支持多用戶同時(shí)購物

第三階段:關(guān)門結(jié)算(異步清算流程)

用戶動(dòng)作:關(guān)閉柜門 → 自動(dòng)觸發(fā)結(jié)算

核心清算流程

關(guān)門信號(hào) → 啟動(dòng)異步任務(wù) → 數(shù)據(jù)收集 → 三重校驗(yàn) → 支付扣款 → 狀態(tài)更新

詳細(xì)步驟

  1. 觸發(fā)結(jié)算:門磁傳感器檢測(cè)到關(guān)門動(dòng)作
  2. 異步處理:避免用戶等待,另起線程處理復(fù)雜計(jì)算
  3. 數(shù)據(jù)收集:獲取關(guān)門快照和最終傳感器數(shù)據(jù)
  4. 三重校驗(yàn)
    • 視覺對(duì)比:開門vs關(guān)門圖片差異分析
    • 重量分析:各貨道重量變化計(jì)算
    • 事件復(fù)核:核對(duì)實(shí)時(shí)記錄的事件序列
  5. 沖突解決:當(dāng)三種方式結(jié)果不一致時(shí)的智能決策
  6. 支付執(zhí)行:調(diào)用支付接口完成扣款
  7. 狀態(tài)更新:標(biāo)記訂單完成,清理緩存

示例代碼實(shí)現(xiàn)

1. 核心數(shù)據(jù)模型

// 訂單實(shí)體
@Entity
@Table(name = "vending_orders")
@Data
public class VendingOrder {
    @Id
    private String orderId;
    private String userId;          // 用戶ID
    private String deviceId;        // 設(shè)備ID
    private String status;          // 狀態(tài): OPEN/CLOSED/PAID/FAILED
    private BigDecimal amount;      // 訂單金額
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
}
// Redis緩存中的設(shè)備會(huì)話
@Data
public class DeviceSession {
    private String sessionId;
    private String deviceId;
    private String orderId;
    private String userId;
    private String status;          // 會(huì)話狀態(tài)
    private LocalDateTime startTime;
    private List<DeviceEvent> events; // 購物事件記錄
}
// 設(shè)備事件
@Data
public class DeviceEvent {
    private String eventId;
    private String deviceId;
    private String orderId;
    private String type;            // PICK/PUT_BACK
    private String productId;
    private LocalDateTime eventTime;
    private String position;        // 貨道位置
}

2. 控制器層 - 處理HTTP請(qǐng)求

@RestController
@RequestMapping("/api/vending")
@Slf4j
public class VendingController {
    @Autowired
    private VendingService vendingService;
    @Autowired
    private SettlementService settlementService;
    /**
     * 掃碼開門接口
     */
    @PostMapping("/open")
    public ResponseEntity<ApiResponse> openDevice(
            @RequestParam String deviceId,
            @RequestParam String authToken) {
        log.info("收到開門請(qǐng)求: deviceId={}", deviceId);
        try {
            OpenResult result = vendingService.processOpenDevice(deviceId, authToken);
            return ResponseEntity.ok(ApiResponse.success(result));
        } catch (BusinessException e) {
            log.warn("開門業(yè)務(wù)異常: {}", e.getMessage());
            return ResponseEntity.badRequest().body(ApiResponse.error(e.getMessage()));
        }
    }
    /**
     * 查詢訂單狀態(tài)
     */
    @GetMapping("/order/{orderId}")
    public ResponseEntity<ApiResponse> getOrderStatus(@PathVariable String orderId) {
        VendingOrder order = vendingService.getOrderById(orderId);
        return ResponseEntity.ok(ApiResponse.success(order));
    }
}
// 統(tǒng)一API響應(yīng)格式
@Data
class ApiResponse {
    private boolean success;
    private String message;
    private Object data;
    public static ApiResponse success(Object data) {
        ApiResponse response = new ApiResponse();
        response.setSuccess(true);
        response.setData(data);
        return response;
    }
    public static ApiResponse error(String message) {
        ApiResponse response = new ApiResponse();
        response.setSuccess(false);
        response.setMessage(message);
        return response;
    }
}

3. 核心服務(wù)層 - 開門處理

@Service
@Slf4j
public class VendingService {
    @Autowired
    private UserAuthService authService;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private MqttService mqttService;
    /**
     * 處理開門請(qǐng)求的核心邏輯
     */
    public OpenResult processOpenDevice(String deviceId, String authToken) {
        // 1. 用戶身份驗(yàn)證
        String userId = authService.verifyWechatToken(authToken);
        if (userId == null) {
            throw new BusinessException("用戶身份驗(yàn)證失敗");
        }
        // 2. 檢查設(shè)備狀態(tài)
        DeviceStatus deviceStatus = deviceService.getDeviceStatus(deviceId);
        if (!deviceStatus.isAvailable()) {
            throw new BusinessException("設(shè)備暫不可用: " + deviceStatus.getStatus());
        }
        // 3. 創(chuàng)建訂單
        VendingOrder order = orderService.createOrder(userId, deviceId);
        log.info("創(chuàng)建訂單成功: orderId={}, userId={}, deviceId={}", 
                order.getOrderId(), userId, deviceId);
        // 4. 創(chuàng)建設(shè)備會(huì)話并緩存
        DeviceSession session = createDeviceSession(deviceId, order);
        cacheDeviceSession(session);
        // 5. 鎖定設(shè)備,避免重復(fù)開門
        deviceService.lockDevice(deviceId, order.getOrderId());
        // 6. 發(fā)送開門指令
        mqttService.sendOpenCommand(deviceId);
        // 7. 請(qǐng)求設(shè)備上報(bào)初始狀態(tài)
        mqttService.requestInitialSnapshot(deviceId);
        return new OpenResult(order.getOrderId(), deviceId, "開門指令已發(fā)送");
    }
    private DeviceSession createDeviceSession(String deviceId, VendingOrder order) {
        DeviceSession session = new DeviceSession();
        session.setSessionId(UUID.randomUUID().toString());
        session.setDeviceId(deviceId);
        session.setOrderId(order.getOrderId());
        session.setUserId(order.getUserId());
        session.setStatus("OPEN");
        session.setStartTime(LocalDateTime.now());
        session.setEvents(new ArrayList<>());
        return session;
    }
    private void cacheDeviceSession(DeviceSession session) {
        String key = buildSessionKey(session.getDeviceId());
        redisTemplate.opsForValue().set(key, session, Duration.ofMinutes(10));
        log.debug("設(shè)備會(huì)話已緩存: key={}", key);
    }
    private String buildSessionKey(String deviceId) {
        return "vending:session:" + deviceId;
    }
}

4. MQTT消息處理 - 設(shè)備通信

@Component
@Slf4j
public class MqttMessageHandler {
    @Autowired
    private VendingService vendingService;
    @Autowired
    private SettlementService settlementService;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    /**
     * 處理關(guān)門事件 - 觸發(fā)結(jié)算流程
     */
    @MqttListener(topics = "device/${spring.application.env}/+/event/door_close")
    public void handleDoorClose(String message) {
        try {
            DoorCloseEvent event = JSON.parseObject(message, DoorCloseEvent.class);
            log.info("收到關(guān)門事件: deviceId={}", event.getDeviceId());
            // 異步處理結(jié)算,不阻塞MQTT線程
            CompletableFuture.runAsync(() -> {
                settlementService.startSettlementProcess(event.getDeviceId());
            });
        } catch (Exception e) {
            log.error("處理關(guān)門事件失敗: message={}", message, e);
        }
    }
    /**
     * 處理商品拿取/放回事件
     */
    @MqttListener(topics = "device/${spring.application.env}/+/event/product")
    public void handleProductEvent(String message) {
        try {
            ProductEvent event = JSON.parseObject(message, ProductEvent.class);
            log.debug("處理商品事件: deviceId={}, type={}, product={}", 
                     event.getDeviceId(), event.getEventType(), event.getProductId());
            // 記錄到Redis緩存
            recordProductEvent(event);
        } catch (Exception e) {
            log.error("處理商品事件失敗: message={}", message, e);
        }
    }
    /**
     * 處理設(shè)備上報(bào)的初始/最終快照
     */
    @MqttListener(topics = "device/${spring.application.env}/+/snapshot")
    public void handleSnapshot(String message) {
        try {
            DeviceSnapshot snapshot = JSON.parseObject(message, DeviceSnapshot.class);
            log.info("處理設(shè)備快照: deviceId={}, type={}", 
                    snapshot.getDeviceId(), snapshot.getSnapshotType());
            // 存儲(chǔ)快照數(shù)據(jù),用于后續(xù)對(duì)比分析
            storeDeviceSnapshot(snapshot);
        } catch (Exception e) {
            log.error("處理快照失敗: message={}", message, e);
        }
    }
    private void recordProductEvent(ProductEvent event) {
        String sessionKey = "vending:session:" + event.getDeviceId();
        DeviceSession session = (DeviceSession) redisTemplate.opsForValue().get(sessionKey);
        if (session != null) {
            DeviceEvent deviceEvent = convertToDeviceEvent(event, session.getOrderId());
            session.getEvents().add(deviceEvent);
            redisTemplate.opsForValue().set(sessionKey, session, Duration.ofMinutes(10));
        }
    }
}

5. 結(jié)算服務(wù) - 核心業(yè)務(wù)邏輯

@Service
@Slf4j
public class SettlementService {
    @Autowired
    private OrderService orderService;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private PaymentService paymentService;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private NotificationService notificationService;
    /**
     * 啟動(dòng)結(jié)算流程
     */
    @Async("settlementExecutor")
    public void startSettlementProcess(String deviceId) {
        log.info("開始結(jié)算流程: deviceId={}", deviceId);
        try {
            // 1. 獲取設(shè)備會(huì)話
            DeviceSession session = getDeviceSession(deviceId);
            if (session == null) {
                log.error("設(shè)備會(huì)話不存在: deviceId={}", deviceId);
                return;
            }
            // 2. 更新訂單狀態(tài)為結(jié)算中
            orderService.updateOrderStatus(session.getOrderId(), "SETTLING");
            // 3. 獲取設(shè)備上報(bào)的最終數(shù)據(jù)
            SettlementData settlementData = collectSettlementData(deviceId);
            // 4. 執(zhí)行結(jié)算計(jì)算
            SettlementResult result = calculateSettlement(settlementData);
            // 5. 處理支付
            boolean paymentSuccess = processPayment(session, result);
            // 6. 更新訂單狀態(tài)
            updateOrderAfterSettlement(session, result, paymentSuccess);
            // 7. 清理資源
            cleanupAfterSettlement(deviceId, session.getOrderId());
            log.info("結(jié)算流程完成: deviceId={}, orderId={}, success={}", 
                    deviceId, session.getOrderId(), paymentSuccess);
        } catch (Exception e) {
            log.error("結(jié)算流程異常: deviceId={}", deviceId, e);
            handleSettlementFailure(deviceId, e);
        }
    }
    /**
     * 收集結(jié)算所需的所有數(shù)據(jù)
     */
    private SettlementData collectSettlementData(String deviceId) {
        SettlementData data = new SettlementData();
        // 獲取初始和最終快照
        data.setInitialSnapshot(deviceService.getInitialSnapshot(deviceId));
        data.setFinalSnapshot(deviceService.getFinalSnapshot(deviceId));
        // 獲取重量傳感器數(shù)據(jù)
        data.setWeightData(deviceService.getWeightSensorData(deviceId));
        // 獲取購物事件記錄
        data.setProductEvents(getRecordedEvents(deviceId));
        return data;
    }
    /**
     * 核心結(jié)算算法 - 三重校驗(yàn)
     */
    private SettlementResult calculateSettlement(SettlementData data) {
        // 1. 視覺對(duì)比分析
        List<Product> visualProducts = analyzeVisualChanges(
            data.getInitialSnapshot(), 
            data.getFinalSnapshot()
        );
        // 2. 重量變化分析
        List<Product> weightProducts = analyzeWeightChanges(data.getWeightData());
        // 3. 事件記錄分析
        List<Product> eventProducts = analyzeEventSequence(data.getProductEvents());
        // 4. 沖突解決和結(jié)果融合
        return resolveProductConflicts(visualProducts, weightProducts, eventProducts);
    }
    /**
     * 沖突解決策略
     */
    private SettlementResult resolveProductConflicts(List<Product> visualProducts, 
                                                    List<Product> weightProducts,
                                                    List<Product> eventProducts) {
        SettlementResult result = new SettlementResult();
        // 策略1: 視覺識(shí)別優(yōu)先(最直接證據(jù))
        Map<String, Product> productMap = new HashMap<>();
        // 首先信任視覺識(shí)別結(jié)果
        for (Product product : visualProducts) {
            productMap.put(product.getPosition(), product);
        }
        // 用重量數(shù)據(jù)驗(yàn)證和補(bǔ)充
        for (Product weightProduct : weightProducts) {
            Product visualProduct = productMap.get(weightProduct.getPosition());
            if (visualProduct == null) {
                // 視覺沒識(shí)別到但重量有變化,信任重量數(shù)據(jù)
                productMap.put(weightProduct.getPosition(), weightProduct);
            }
        }
        // 用事件記錄進(jìn)行最終校驗(yàn)
        result.setFinalProducts(new ArrayList<>(productMap.values()));
        result.setConflictResolved(true);
        log.debug("沖突解決完成: 視覺識(shí)別{}個(gè), 重量變化{}個(gè), 最終確認(rèn){}個(gè)", 
                 visualProducts.size(), weightProducts.size(), result.getFinalProducts().size());
        return result;
    }
}

6. 支付服務(wù)

@Service
@Slf4j
public class PaymentService {
    @Autowired
    private WechatPayService wechatPayService;
    @Autowired
    private OrderService orderService;
    /**
     * 執(zhí)行支付
     */
    public boolean processPayment(DeviceSession session, SettlementResult result) {
        try {
            PaymentRequest request = new PaymentRequest();
            request.setUserId(session.getUserId());
            request.setOrderId(session.getOrderId());
            request.setAmount(calculateTotalAmount(result.getFinalProducts()));
            request.setDescription("智能售貨柜購物");
            PaymentResponse response = wechatPayService.unifiedOrder(request);
            if ("SUCCESS".equals(response.getResultCode())) {
                log.info("支付成功: orderId={}, amount={}", 
                        session.getOrderId(), request.getAmount());
                return true;
            } else {
                log.warn("支付失敗: orderId={}, error={}", 
                        session.getOrderId(), response.getErrMsg());
                return false;
            }
        } catch (Exception e) {
            log.error("支付處理異常: orderId={}", session.getOrderId(), e);
            return false;
        }
    }
    private BigDecimal calculateTotalAmount(List<Product> products) {
        return products.stream()
                .map(Product::getPrice)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
}

7. 配置類

@Configuration
@EnableAsync
@EnableScheduling
public class AsyncConfig {
    @Bean("settlementExecutor")
    public TaskExecutor settlementTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("settlement-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
}
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        return template;
    }
}

總結(jié)

1.異步處理:結(jié)算流程異步化,用戶無需等待 2.三重校驗(yàn):視覺+重量+事件記錄,確保準(zhǔn)確率 3.實(shí)時(shí)通信:MQTT保證設(shè)備與后臺(tái)實(shí)時(shí)通信 4.緩存優(yōu)化:Redis提升系統(tǒng)響應(yīng)速度 5.異常容錯(cuò):完善的異常處理機(jī)制

這種系統(tǒng)完美融合了物聯(lián)網(wǎng)、云計(jì)算、移動(dòng)支付等前沿技術(shù),為用戶提供了拿了就走的無感購物體驗(yàn),代表了零售行業(yè)數(shù)字化轉(zhuǎn)型的最新成果。

到此這篇關(guān)于SpringBoot + MQTT實(shí)現(xiàn)取貨就走的智能售貨柜系統(tǒng)完整流程的文章就介紹到這了,更多相關(guān)SpringBoot MQTT智能售貨柜系統(tǒng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Eclipse 出現(xiàn)A configuration with this name already exists問題解決方法

    Eclipse 出現(xiàn)A configuration with this name already exists問題解決方

    這篇文章主要介紹了Eclipse 出現(xiàn)A configuration with this name already exists問題解決方法的相關(guān)資料,需要的朋友可以參考下
    2016-11-11
  • springboot上傳文件過大的500異常解決

    springboot上傳文件過大的500異常解決

    這篇文章主要介紹了springboot上傳文件過大的500異常解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • IDEA?Debug過程中使用Drop?Frame或Reset?Frame實(shí)現(xiàn)操作回退的方法

    IDEA?Debug過程中使用Drop?Frame或Reset?Frame實(shí)現(xiàn)操作回退的方法

    在IDEA中就提供了一個(gè)幫助你回退代碼的機(jī)會(huì),但這個(gè)方法并不是萬能的,好了,下面就來具體說說IDEA?Debug過程中使用Drop?Frame或Reset?Frame實(shí)現(xiàn)操作回退的方法,感興趣的朋友一起看看吧
    2022-04-04
  • 在Spring框架下配置Quartz集群的詳細(xì)步驟(MySQL數(shù)據(jù)源)

    在Spring框架下配置Quartz集群的詳細(xì)步驟(MySQL數(shù)據(jù)源)

    Quartz 是一個(gè)功能強(qiáng)大的調(diào)度庫,可以在 Java 應(yīng)用中用于執(zhí)行定時(shí)任務(wù),本文將介紹如何在 Spring 框架下配置 Quartz 集群,并使用 MySQL 作為數(shù)據(jù)源來存儲(chǔ)調(diào)度信息,文中有詳細(xì)的代碼供大家參考,需要的朋友可以參考下
    2025-01-01
  • SpringBoot使用MyBatis的XML文件進(jìn)行SQL語句編寫

    SpringBoot使用MyBatis的XML文件進(jìn)行SQL語句編寫

    在現(xiàn)代 Java Web 開發(fā)中,Spring Boot 和 MyBatis 是兩個(gè)非常流行的技術(shù)框架,本文將詳細(xì)介紹如何在 Spring Boot 項(xiàng)目中使用 MyBatis 的 XML 文件來編寫 SQL 語句,感興趣的可以了解下
    2025-07-07
  • SpringBoot實(shí)現(xiàn)動(dòng)態(tài)端口切換黑魔法

    SpringBoot實(shí)現(xiàn)動(dòng)態(tài)端口切換黑魔法

    這篇文章主要為大家詳細(xì)介紹了SpringBoot如何實(shí)現(xiàn)動(dòng)態(tài)端口切換黑魔法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-12-12
  • maven package后Idea項(xiàng)目中找不到target文件的解決

    maven package后Idea項(xiàng)目中找不到target文件的解決

    在Idea中執(zhí)行mavenpackage打包后,target文件不顯示,點(diǎn)擊「ShowinExplore」可以在本地文件夾中查到,解決方法:在Idea的Maven工具窗口中,右鍵點(diǎn)擊項(xiàng)目,選擇Reimport,刷新項(xiàng)目即可
    2024-11-11
  • idea 開發(fā)神器之idea插件匯總

    idea 開發(fā)神器之idea插件匯總

    這篇文章主要介紹了idea 開發(fā)神器之idea插件匯總,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • Java包裝類與異常處理的過程

    Java包裝類與異常處理的過程

    本文介紹了Java中包裝類和異常處理的概念,解析了它們的用途和使用方法,包裝類主要用于將基本數(shù)據(jù)類型轉(zhuǎn)換為對(duì)象,解決面向?qū)ο缶幊讨械南拗疲划惓L幚頇C(jī)制則幫助程序優(yōu)雅地處理運(yùn)行時(shí)錯(cuò)誤,包括常見異常類型、異常處理語句及自定義異常的使用
    2026-04-04
  • 詳解Java編程中線程的掛起、恢復(fù)和終止的方法

    詳解Java編程中線程的掛起、恢復(fù)和終止的方法

    這篇文章主要介紹了詳解Java編程中線程的掛起、恢復(fù)和終止的方法,線程是Java學(xué)習(xí)中的重點(diǎn)和難點(diǎn)知識(shí),需要的朋友可以參考下
    2015-09-09

最新評(píng)論

左贡县| 奉化市| 马边| 巴彦县| 白河县| 江华| 京山县| 舟山市| 祁门县| 临邑县| 汉沽区| 牡丹江市| 钟祥市| 鲁山县| 专栏| 磐安县| 泾源县| 武定县| 巴马| 凤山市| 开封县| 靖远县| 亚东县| 南京市| 府谷县| 昭苏县| 佛教| 榆林市| 洛宁县| 兴城市| 安多县| 云林县| 仲巴县| 敦煌市| 鄂州市| 诸城市| 垫江县| 万宁市| 巴彦淖尔市| 革吉县| 天柱县|