版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、异常 异常的定义 在java编程思想中这样定义 异常:阻止当前方法或作用域继续执行的问题。虽然java中有异常处理机制,但是要明确一点,决不应该用"正常"的态度来看待异常。绝对一点说异常就是某种意义上的错误,就是问题,它可能会导致程序失败。之所以java要提出异常处理机制,就是要告诉开发人员,你的程序出现了不正常的情况,请注意。 记得当初学习java的时候,异常总是搞不太清楚,不知道这个异常是什么意思,为什么会有这个机制?但是随着知识的积累逐渐也对异常有一点感觉了。 调用抛出异常的方法,必须处理异常,有两种方式: 1、使用try catch finally 捕获。 2、直接
2、再抛出异常。 注:处理异常的方式依赖于具体业务逻辑,可灵活处理。 如果代码有异常发生,异常以后的代码将不再执行。 举一个例子来说明一下异常的用途。public class Calculator public int devide(int num1, int num2) / 判断除数是否为0if (num2 = 0) throw new IllegalArgumentException("除数不能为零");return num1 / num2; 看一下这个类中关于除运算的方法,如果你是新手你可能会直接返回计算结果,根本不去考虑什么参数是否正确,是否合法(当然可以原谅,谁都是这
3、样过来的)。但是我们应尽可能的考虑周全,把可能导致程序失败的"苗头"扼杀在摇篮中,所以进行参数的合法性检查就很有必要了。 其中执行参数检查抛出来的那个参数非法异常,这就属于这个方法的不正常情况。正常情况下我们会正确的使用计算器,但是不排除粗心大意把除数赋值为0。 如果你之前没有考虑到这种情况,并且恰巧用户数学基础不好,那么你完了。但是如果你之前考虑到了这种情况,那么很显然错误已在你的掌控之中。异常案例:public class User int id;String email;String pwd;public User() public User(int id, Stri
4、ng email, String pwd) super();this.id = id;this.email = email;this.pwd = pwd;Overridepublic String toString() return id + "," + email;Overridepublic boolean equals(Object obj) if (obj = null) return false;if (this = obj) return true;if (obj instanceof User) User o = (User) obj;return id =
5、o.id;return false;Overridepublic int hashCode() return id;-import java.util.HashMap;import java.util.Map;/* * 该类提供用户管理功能:注册和登录 */public class UserManager / 存储user对象的集合,key是email,value是用户private Map<String, User> users = new HashMap<String, User>();private int id = 1;public User reg(Strin
6、g email, String pwd) throws UserExsitsException if (users.containsKey(email) throw new UserExsitsException("该邮箱" + email + "已存在!");User newuser = new User(id+, email, pwd);users.put(email, newuser);return newuser;public User login(String email, String pwd) throws EmailOrPwdExcept
7、ion if (!users.containsKey(email) throw new EmailOrPwdException("无此用户!");User u = users.get(email);if (!u.pwd.equals(pwd) throw new EmailOrPwdException("密码错误!");return u;/* * 该类表示用户已注册过异常,一定继承于excetpion类 * 用于表示注册时可能已经注册过异常 */class UserExsitsException extends Exception public User
8、ExsitsException(String message) super(message);/* * 该类表示用户名或密码错误异常,一定继承于exception类 * 用于表示输入的用户名或密码错误异常 */class EmailOrPwdException extends Exception public EmailOrPwdException(String message) super(message);-public class ExceptionDemo public static void main(String args) throws Exception UserManager
9、 mgr = new UserManager();User u = mgr.reg("java_manual", "123abc");System.out.println("注册成功!");/ 测试1,重复注册,出现异常u = mgr.reg("java_manual", "123abc");/ 测试2,登录密码错误,出现异常,密码不对u = mgr.login("java_manual", "abc");/ 测试3,登陆成功!User someone =
10、 mgr.login("java_manual", "123abc");System.out.println(someone); 注: 代码调用抛出异常的方法,必须处理异常,有两种方式: 1、使用try catch finally 捕获。
11、; 2、直接再抛出异常。 处理异常的方式依赖于具体业务逻辑,可灵活处理。 1) try 是尝试运程代码块,如果有异常会被随后的catch捕获,异常发生以后代码不执行。 2) catch代码块是异常处理代码,需要提供合理的处理。
12、160;1、异常的处理是不具体业务逻辑有关。 2、可以写多个catch处理一系列异常,但是要注意:异常的大小关系,大类型的放到后面处理。 3) 有的时候直接catch(Exception) 粗粒度处理异常,代码简洁,语义含糊. 根据业务逻辑适 当选用。 4) fina
13、lly代码块,不管是否出现异常,总会执行的代码块。 1、finally经常用来处理现场的清理,比如:可靠的数据库连接关闭。 5) 处理异常有一个基本原则:能够底层处理的尽量处理,但是如果不能处理,必须抛出到调用者 (方法)。不应该简单的抛弃。 6) 异常捕获再抛出, 是一种把底
14、层异常迚行封装,转换为另外一种异常类型。 7) * 建议在捕获到异常时候使用e.printStackTrace(),打印到控制台。 1、输出内容是:出现异常时候的方法调用堆栈。 2、一般情况下,凡是捕获异常代码都输出:e.printStackTrace()
15、60; 【案例1】用户登录及异常处理_try catcvh捕捉异常 版本01 ExceptionDemo2.javapublic class ExceptionDemo2 public static void main(String args) UserManager mgr = new UserManager();try User u = mgr.re
16、g("java_manual", "123abc");System.out.println("注册成功!");User someone = mgr.login("java_manual", "123abc");System.out.println(someone); catch (UserExsitsException e) e.printStackTrace(); catch (EmailOrPwdException e) e.printStackTrace();import java.uti
17、l.Scanner;public class ExceptionDemo3 public static void main(String args) UserManager mgr = new UserManager();Scanner s = new Scanner(System.in);while (true) System.out.println("1.注册 2. 登录");String cmd = s.nextLine();if ("1".equals(cmd) / 注册用户System.out.println("email:"
18、;);String email = s.nextLine();System.out.println("密码:");String pwd = s.nextLine();try User u = mgr.reg(email, pwd);System.out.println("注册成功:" + u); catch (UserExsitsException e) e.printStackTrace(); else if ("2".equals(cmd) / 用户登录System.out.println("email:");
19、String email = s.nextLine();System.out.println("密码:");String pwd = s.nextLine();try User u = mgr.login(email, pwd);System.out.println("注册成功:" + u); catch (EmailOrPwdException e) e.printStackTrace(); else System.out.println("不可识别的命令!");/* * 经典笔试题目: 如下程序的执行结果是什么? * A 0,0,
20、5 B 1,01 C 4,0,5 D 4,4,4 */public class TryCatchDemo public static void main(String args) System.out.println(test(null) + "," + test("0") + "," + test("");private static int test(String str) try return str.charAt(0) - '0' catch (NullPointerException e)
21、 e.printStackTrace();return 1; catch (RuntimeException e) e.printStackTrace();return 2; catch (Exception e) e.printStackTrace();return 3; finally return 4;/java.lang.NullPointerExceptionat basic.exception.TryCatchDemo.test(TryCatchDemo.java:14)at basic.exception.TryCatchDemo.main(TryCatchD
22、emo.java:9)java.lang.StringIndexOutOfBoundsException: String index out of range: 0at java.lang.String.charAt(Unknown Source)at basic.exception.TryCatchDemo.test(TryCatchDemo.java:14)at basic.exception.TryCatchDemo.main(TryCatchDemo.java:9)4,4,4 注: 1、
23、本案例在语法上允许(只是警告),但工作中丌会出现,仅作为演示。 2、案例return 了2次(catch一次,finally一次)。 3、finally永远会被执行。 4、捕获(catch)异常有顺序,异常“由小到大”,否则会出编译错误。 5、NullPointerException 空指针异常。 6、StringIndexOutOfBoundsException 字符串下标越界。异常分类:Throwable |-Error 是系统不可恢复的错误,JVM发生的错误 | |-OutOfMemoryError 堆内存溢出 | |
24、-StackOverflowError 栈内存溢出 |-Exception 程序可以检查处理的异常,常见的异常继承根 |-java.text.ParseException format 解析对象时候发生 | 如:Date d = dateformat.parse("2010-5-5"); |-RuntimeException 非检查异常,Javac忽略对这类异常的语法检查 |-IllegalArgumentException
25、|-NullPointerException |-ArrayIndexOutOfBoundsException |-ClassCastException |-NumberFormatException * Integer.parseInt(S) 关于异常的分类: 1、Throwable 类是 Java 语言中所有错误或异常的超类(这就是一切皆可抛的东西)。它有两个子类:Error和Exception。 2、Error:用于指示合理的应用程序不应该试图捕获的严重问题。这种情况是很大的问题,大到你不能处理了,所以听之任之就行了,你不用管它。比如说V
26、irtualMachineError:当Java虚拟机崩溃或用尽了它继续操作所需的资源时,抛出该错误。好吧,就算这个异常的存在了,那么应该何时,如何处理它呢?交给JVM吧,没有比它更专业的了。 3、Exception:它指出了合理的应用程序想要捕获的条件。Exception又分为两类:一种是CheckedException,一种是UncheckedException。这两种Exception的区别主要是CheckedException需要用try.catch.显示的捕获,而UncheckedException不需要捕获。通常UncheckedException又叫做RuntimeExcepti
27、on。effective java指出:对于可恢复的条件使用被检查的异常(CheckedException),对于程序错误(言外之意不可恢复,大错已经酿成)使用运行时异常(RuntimeException)。 4、我们常见的RuntimeExcepiton有IllegalArgumentException、IllegalStateException、NullPointerException、IndexOutOfBoundsException等等。对于那些CheckedException就不胜枚举了,我们在编写程序过程中try.catch.捕捉的异常都是CheckedException。io包中
28、的IOException及其子类,这些都是CheckedException。自定义异常: 软件中会大量使用自定义异常,一般从Exception继承异常类命名要有实际意义, 一般都手工继承父类的构造器。 使用Eclipse工具从父类创建构造器/* 用户注册过的异常,一定要继承于exception类 */public class UserExsitException extends Exception public UserExsitException() super();public UserExsitException(String message, Throwable cause) supe
29、r(message, cause);public UserExsitException(String message) super(message);异常的使用: 在异常的使用这一部分主要是演示代码,都是我们平常写代码的过程中会遇到的(当然只是一小部分),抛砖引玉吗! 例1. 这个例子主要通过两个方法对比来演示一下有了异常以后代码的执行流程。public static void testException1() int ints = new int 1, 2, 3, 4 ;System.out.println("异常出现前");try System.out.println(
30、ints4);System.out.println("我还有幸执行到吗");/ 发生异常以后,后面的代码不能被执行 catch (IndexOutOfBoundsException e) System.out.println("数组越界错误");System.out.println("异常出现后");/* * output: 异常出现前 数组越界错误 4 异常出现后 */public static void testException2() int ints = new int 1, 2, 3, 4 ;System.out.print
31、ln("异常出现前");System.out.println(ints4);System.out.println("我还有幸执行到吗");/ 发生异常以后,他后面的代码不能被执行 首先指出例子中的不足之处,IndexOutofBoundsException是一个非受检异常,所以不用try.catch.显示捕捉,但是我的目的是对同一个异常用不同的处理方式,看它会有什么不同的而结果(这里也就只能用它将就一下了)。异常出现时第一个方法只是跳出了try块,但是它后面的代码会照样执行的。但是第二种就不一样了直接跳出了方法,比较强硬。从第一个方法中我们看到,try.
32、catch.是一种"事务性"的保障,它的目的是保证程序在异常的情况下运行完毕,同时它还会告知程序员程序中出错的详细信息(这种详细信息有时要依赖于程序员设计)。 例2. 重新抛出异常import java.io.BufferedInputStream;import java.io.FileInputStream;import java.io.FileNotFoundException;public class Rethrow public static void readFile(String file) throws FileNotFoundException try Bu
33、fferedInputStream in = new BufferedInputStream(new FileInputStream(file); catch (FileNotFoundException e) e.printStackTrace();System.err.println("不知道如何处理该异常或者根本不想处理它,但是不做处理又不合适,这是重新抛出异常交给上一级处理");/ 重新抛出异常throw e;public static void printFile(String file) try readFile(file); catch (FileNotFou
34、ndException e) e.printStackTrace();public static void main(String args) printFile("D:/file"); 异常的本意是好的,让我们试图修复程序,但是现实中我们修复的几率很小,我们很多时候就是用它来记录出错的信息。如果你厌倦了不停的处理异常,重新抛出异常对你来说可能是一个很好的解脱。原封不动的把这个异常抛给上一级,抛给调用这个方法的人,让他来费脑筋吧。这样看来,java异常(当然指的是受检异常)又给我们平添很多麻烦,尽管它的出发点是好的。 例3. 异常链的使用及异常丢失 定义三个异常类:Exce
35、ptionA,ExceptionB,ExceptionCpublic class ExceptionA extends Exception public ExceptionA(String str) super(); public class ExceptionB extends ExceptionA public ExceptionB(String str) super(str);public class ExceptionC extends ExceptionA public ExceptionC(String str) super(str); 异常丢失的情况:public class N
36、everCaught static void f() throws ExceptionB throw new ExceptionB("exception b");static void g() throws ExceptionC try f(); catch (ExceptionB e) ExceptionC c = new ExceptionC("exception a");throw c;public static void main(String args) try g(); catch (ExceptionC e) e.printStackTra
37、ce();/* * exception.ExceptionC at exception.NeverCaught.g(NeverCaught.java:12) at * exception.NeverCaught.main(NeverCaught.java:19) */ 为什么只是打印出来了ExceptionC而没有打印出ExceptionB呢?这个还是自己分析一下吧! 上面的情况相当于少了一种异常,这在我们排错的过程中非常的不利。那我们遇到上面的情况应该怎么办呢?这就是异常链的用武之地:保存异常信息,在抛出另外一个异常的同时不丢失原来的异常。public class NeverCaught2
38、static void f() throws ExceptionB throw new ExceptionB("exception b");static void g() throws ExceptionC try f(); catch (ExceptionB e) ExceptionC c = new ExceptionC("exception a");/ ?c.initCause(e);throw c;public static void main(String args) try g(); catch (ExceptionC e) e.printS
39、tackTrace();/* * exception.ExceptionC at exception.NeverCaught.g(NeverCaught.java:12) at * exception.NeverCaught.main(NeverCaught.java:21) Caused by: * exception.ExceptionB at exception.NeverCaught.f(NeverCaught.java:5) at * exception.NeverCaught.g(NeverCaught.java:10) . 1 more */ 这个异常链的特性是所有异常均具备的,
40、因为这个initCause()方法是从Throwable继承的。 例4. 清理工作 清理工作对于我们来说是必不可少的,因为如果一些消耗资源的操作,比如IO,JDBC。如果我们用完以后没有及时正确的关闭,那后果会很严重,这意味着内存泄露。异常的出现要求我们必须设计一种机制不论什么情况下,资源都能及时正确的清理。这就是finally。public void readFile(String file) BufferedReader reader = null;try reader = new BufferedReader(new InputStreamReader(new FileInputStre
41、am(file);/ do some other work catch (FileNotFoundException e) e.printStackTrace(); finally try reader.close(); catch (IOException e) e.printStackTrace(); 例子非常的简单,是一个读取文件的例子。这样的例子在JDBC操作中也非常的常见。(所以,我觉得对于资源的及时正确清理是一个程序员的基本素质之一。) Try.finally结构也是保证资源正确关闭的一个手段。如果你不清楚代码执行过程中会发生什么异常情况会导致资源不能得到清理,那么你就用try对这
42、段"可疑"代码进行包装,然后在finally中进行资源的清理。举一个例子:public void readFile() BufferedReader reader = null;try reader = new BufferedReader(new InputStreamReader(new FileInputStream("file");/ do some other work/ close readerreader.close(); catch (FileNotFoundException e) e.printStackTrace(); catch
43、(IOException e) e.printStackTrace(); 我们注意一下这个方法和上一个方法的区别,下一个人可能习惯更好一点,及早的关闭reader。但是往往事与愿违,因为在reader.close()以前异常随时可能发生,这样的代码结构不能预防任何异常的出现。因为程序会在异常出现的地方跳出,后面的代码不能执行(这在上面应经用实例证明过)。这时我们就可以用try.finally来改造:public void readFile2() BufferedReader reader = null;try try reader = new BufferedReader(new InputS
44、treamReader(new FileInputStream("file");/ do some other work/ close reader finally reader.close(); catch (FileNotFoundException e) e.printStackTrace(); catch (IOException e) e.printStackTrace(); 及早的关闭资源是一种良好的行为,因为时间越长你忘记关闭的可能性越大。这样在配合上try.finally就保证万无一失了(不要嫌麻烦,java就是这么中规中矩)。 再说一种情况,假如我想在构造
45、方法中打开一个文件或者创建一个JDBC连接,因为我们要在其他的方法中使用这个资源,所以不能在构造方法中及早的将这个资源关闭。那我们是不是就没辙了呢?答案是否定的。 看一下下面的例子:mport java.io.BufferedReader;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStreamReader;public class ResourceInConstructor BufferedReader re
46、ader = null;public ResourceInConstructor() try reader = new BufferedReader(new InputStreamReader(new FileInputStream(""); catch (FileNotFoundException e) e.printStackTrace();public void readFile() try while (reader.readLine() != null) / do some work catch (IOException e) e.printStackTrace(
47、);public void dispose() try reader.close(); catch (IOException e) e.printStackTrace(); 这一部分讲的多了一点,但是异常确实是看起来容易用起来难的东西呀,java中还是有好多的东西需要深挖的。 对于异常的误用着实很常见,上一部分中已经列举了几个,大家仔细的看一下。下面再说两个其他的。 例1. 用一个Exception来捕捉所有的异常,颇有"一夫当关万夫莫开"的气魄。不
48、过这也是最傻的行为。public void readFile3(String file) BufferedReader reader = null;Connection conn = null;try reader = new BufferedReader(new InputStreamReader(new FileInputStream(file);/ do some other workconn = DriverManager.getConnection("");/ . catch (Exception e) e.printStackTrace(); finally t
49、ry reader.close();conn.close(); catch (Exception e) e.printStackTrace(); 从异常角度来说这样严格的程序确实是万无一失,所有的异常都能捕获。但是站在编程人员的角度,万一这个程序出错了我们该如何分辨是到底是那引起的呢,IO还是JDBC.所以,这种写法很值得当做一个反例。大家不要以为这种做法很幼稚,傻子才会做。我在公司实习时确实看见了类似的情况:只不过是人家没有用Exception而是用了Throwable。 例2. 这里就不举例子了,上面的程序都是反例。异常是程序处理意外情况的机制,当程序发生意外时,我们需要尽可能多的得到意外
50、的信息,包括发生的位置,描述,原因等等。这些都是我们解决问题的线索。但是上面的例子都只是简单的printStackTrace()。如果我们自己写代码,就要尽可能多的对这个异常进行描述。比如说为什么会出现这个异常,什么情况下会发生这个异常。如果传入方法的参数不正确,告知什么样的参数是合法的参数,或者给出一个sample。 例3. 将try block写的简短,不要所有的东西都扔在这里,我们尽可能的分析出到底哪几行程序可能出现异常,只是对可能出现异常的代码进行try。尽量为每一个异常写一个try.catch,避免异常丢失。在IO操作中,一个IOException也具有"一夫当关万夫莫开&
51、quot;的气魄。 反射 Java语言反射提供一种动态链接程序组件的多功能方法。它允许程序创建和控制任何类的对象(根据安全性限制),无需提前硬编码目标类。这些特性使得反射特别适用于创建以非常普通的方式与对象协作的库。例如,反射经常在持续存储对象为数据库、XML或其它外部格式的框架中使用。Java reflection非常有用,它使类和数据结构能按名称动态检索相关信息,并允许在运行着的程序中操作这些信息。 Java 的这一特性非常强大,并且是其它一些常用语言,如 C、C+、Fortran 或者 Pascal 等都不具备的。 但反射有两个缺点。第一个是性能问题。用于字段和方法接入时反射要远慢于直接
52、代码。性能问题的程度取决于程序中是如何使用反射的。如果它作为程序运行中相对很少涉及的部分,缓慢的性能将不会是一个问题。即使测试中最坏情况下的计时图显示的反射操作只耗用几微秒。仅反射在性能关键的应用的核心逻辑中使用时性能问题才变得至关重要。 许多应用中更严重的一个缺点是使用反射会模糊程序内部实际要发生的事情。程序人员希望在源代码中看到程序的逻辑,反射等绕过了源代码的技术会带来维护问题。反射代码比相应的直接代码更复杂,正如性能比较的代码实例中看到的一样。解决这些问题的最佳方案是保守地使用反射仅在它可以真正增加灵活性的地方记录其在目标类中的使用。 Reflection是Java程序开发语言的特征之一
53、,它允许运行中的Java程序对自身进行检查,或者说"自审",并能直接操作程序的内部属性。例如,使用它能获得Java类中各成员的名称并显示出来。 Java的这一能力在实际应用中也许用得不是很多,但是在其它的程序设计语言中根本就不存在这一特性。例如,Pascal、C或者C+中就没有办法在程序中获得函数定义相关的信息。 JavaBean 是 reflection 的实际应用之一,它能让一些工具可视化的操作软件组件。这些工具通过 reflection 动态的载入并取得Java组件(类)的属性。 在学习反射之前,让我们先了解“类(Class)”。“方法”、“属性”、“类”都是名词,那
54、么相应的在Java中会有这样一些特殊的类:“方法类(Method类)”、“属性类(Field类)”、“构造器类(Constructor类)”、“类类(Class类)”。 如上所示,任何Java的类戒接口都是Class类的一个实例。 反射就是Java自我管理这些(类、对象)的机制。 1) 反射的作用(重点理解) 1、可以通过反射机制发现对象的类型,发现类型的方法/属性/构造器。 2、可以创建对象并访问任意对象方法和属性等。 2) Class加载 类加载到内存:Java将磁盘类文件加载到内存中,为一个对象(实例),这个对象是Class的实例。 3) Class实例代表Java中类型 获得基本类型实
55、例int.classlong.class.Class cls = "abc".getClass();获得类类型(Class)实例:Class cls = String.class; Class cls = Class.forName("java.lang.String"); Class cls = "abc".getClass();以上方法获得的cls是同一个对象, 就是String
56、160;类内存加载的结果。 考虑下面这个简单的例子,让我们看看 reflection 是如何工作的。import java.lang.reflect.*;public class DumpMethods public static void main(String args) try Class c = Class.forName(args0);Method m = c.getDeclaredMethods();for (int i = 0; i < m.length; i+)System.out.println(mi.toString(); catch (Throwable e) System.err.println(e); 按如下语句执行:java Du
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2022教师考核表个人述职报告范文【7篇】
- 结算工作总结模板4篇
- 竞聘演讲稿(集合15篇)
- 元旦晚会有感心得5篇
- 春天周末经典祝福语
- 见习护士自我鉴定集锦15篇
- 消化工作计划合集6篇
- 煤矿岗位工作标准
- 广东省汕头市潮南井都中学2024-2025学年九年级上册语篇填空与补全对话专项练习测试卷(含答案)
- 村屯开展环境整治工作总结(4篇)
- 低浓度颗粒物的测定重量法方法验证报告
- 百家姓全文拼音版A4打印
- 日本签证在职证明
- 专家论证挖孔桩专项施工方案
- IPC标准解析学习课程
- 麻花钻钻孔中常见问题的原因和解决办法
- 博士研究生综合素质及科研能力综合考评评分表
- 外墙真石漆购销合同
- 氟化物测定方法
- 艺体教研组活动记录
- (最新整理)锅炉过热蒸汽温度控制系统方案
评论
0/150
提交评论