JavaWeb开发异常

一 JavaWeb

1、java.lang.UnsupportedClassVersionError

        org/comet4j/core/CometAppListener : unsupported classversion 50.0 (unable to load class org.comet4j.core.CometAppListener)
        at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2822)
        at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1159)

解决办法:http://www.blogjava.net/zhyiwww/archive/2007/01/16/94235.html

2、org.codehaus.xfire.XFireRuntimeException:

Could not find operation queryContentById in the客户端用的jar包不是最新的,也就是说本地客户端调用服务时找不到xxx方法。把本地的jar包干掉,从下一份新的jar包就好

 

4、 SQLException:操作数据库异常类。

frorm:http://www.cnblogs.com/qinqinmeiren/archive/2010/10/14/2151702.html

    现在的Java应用程序大部分都是依赖于数据库运行的。当Java应用程序与数据库进行沟通时如果产生了错误,就会触发这个类。同时会将数据库的错误信息通过这个类显示给用户。也就是说,这个操作数据库异常类是数据库与用户之间异常信息传递的桥梁。如现在用户往系统中插入数据,而在数据库中规定某个字段必须唯一。当用户插入数据的时候,如果这个字段的值跟现有的纪录重复了,违反了数据库的唯一性约束,此时数据库就会跑出一个异常信息。这个信息一般用户可能看不到,因为其发生在数据库层面的。此时这个操作数据库异常类就会捕捉到数据库的这个异常信息,并将这个异常信息传递到前台。如此的话,前台用户就可以根据这个异常信息来分析发生错误的原因。这就是这个操作数据库异常类的主要用途。在Java应用程序中,所有数据库操作发生异常时,都会触发这一个类。所有此时Java应用程序本身的提示信息往往过于笼统,只是说与数据库交互出现错误,没有多大的参考价值。此时反而是数据库的提示信息更加有使用价值。 

5、SQLExceptionlassCastException:数据类型转换异常。


frorm:http://www.cnblogs.com/qinqinmeiren/archive/2010/10/14/2151702.html

    在Java应用程序中,有时候需要对数据类型进行转换。这个转换包括显示的转换与隐式的转换。不过无论怎么转换,都必须要符合一个前提的条件,即数据类型的兼容性。如果在数据转换的过程中,违反了这个原则,那么就会触发数据类型转换异常。如现在在应用程序中,开发人员需要将一个字符型的日期数据转换为数据库所能够接受的日期型数据,此时只需要在前台应用程序中进行控制,一般不会有问题。但是,如果前台应用程序缺乏相关的控制,如用户在输入日期的时候只输入月、日信息,而没有年份的信息。此时应用程序在进行数据类型转换的时候,就会出现异常。根据笔者的经验,数据类型转换异常在应用程序开发中使一个出现的比较多的异常,也是一个比较低级的异常。因为大部分情况下,都可以在应用程序窗口中对数据类型进行一些强制的控制。即在数据类型进行转换之前,就保证数据类型的兼容性。如此的话,就不容易造成数据类型的转换异常。如在只允许数值类型的字段中,可以设置不允许用户输入数值以外的字符。虽然说有了异常处理机制,可以保证应用程序不会被错误的运行。但是在实际开发中,还是要尽可能多的预见错误发生的原因,尽量避免异常的发生。

6、 NumberFormatException:字符串转换为数字类型时抛出的异常。
frorm:http://www.cnblogs.com/qinqinmeiren/archive/2010/10/14/2151702.html

    在数据类型转换过程中,如果是字符型转换为数字型过程中出现的问题,对于这个异常在Java程序中采用了一个独立的异常,即NumberFormatException.如现在讲字符型的数据“123456”转换为数值型数据时,是允许的。但是如果字符型数据中包含了非数字型的字符,如123#56,此时转换为数值型时就会出现异常。系统就会捕捉到这个异常,并进行处理。

7 java.lang.ClassNotFoundException 

1.frorm:http://www.cnblogs.com/qinqinmeiren/archive/2010/10/14/2151702.html 

异常的解释是"指定的类不存在"。

2.http://blog.csdn.net/democreen/article/details/6297043

缺包。。。

如果你来到我着,记住这是个最基础的,问题,有的时候你需要找到这个包,如果包你有还提示这个异常,那么你反编译一下,按目录放到工程里,java的编译原理是,class优先级大于所有加载的jar 优先级,

或许是你少其他的jar包,以及jar包里有问题。

由于我的问题很特殊,我是给的jar包里出现问题,后来改写,为这个,调试了三天,打断点跟踪,真纠结。。。。


8  java.lang.ArithmeticException

frorm:http://www.cnblogs.com/qinqinmeiren/archive/2010/10/14/2151702.html

 这个异常的解释是"数学运算异常",比如程序中出现了除以零这样的运算就会出这样的异常。

9  java.lang.ArrayIndexOutOfBoundsException

frorm:http://www.cnblogs.com/qinqinmeiren/archive/2010/10/14/2151702.html
  异常的解释是"数组下标越界",现在程序中大多都有对数组的操作,因此在调用数组的时候一定要认真检查,看自己调用的下标是不是超出了数组的范围,一般来说,显示(即直接用常数当下标)调用不太容易出这样的错,但隐式(即用变量表示下标)调用就经常出错了,还有一种情况,是程序中定义的数组的长度是通过某些特定方法决定的,不是事先声明的,这个时候,最好先查看一下数组的length,以免出现这个异常。

10  java.lang.IllegalArgumentException

frorm:http://www.cnblogs.com/qinqinmeiren/archive/2010/10/14/2151702.html
  这个异常的解释是"方法的参数错误",比如g.setColor(int red,int green,int blue)这个方法中的三个值,如果有超过255的也会出现这个异常,因此一旦发现这个异常,我们要做的,就是赶紧去检查一下方法调用中的参数传递是不是出现了错误。

11  java.lang.IllegalAccessException

frorm:http://www.cnblogs.com/qinqinmeiren/archive/2010/10/14/2151702.html
  这个异常的解释是"没有访问权限",当应用程序要调用一个类,但当前的方法即没有对该类的访问权限便会出现这个异常。对程序中用了Package的情况下要注意这个异常

 

12  java.lang.NullPointerException

frorm:http://www.cnblogs.com/qinqinmeiren/archive/2010/10/14/2151702.html
  异常的解释是"程序遇上了空指针",简单地说就是调用了未经初始化的对象或者是不存在的对象,即把数组的初始化和数组元素的初始化混淆起来了。数组的初始化是对数组分配需要的空间,而初始化后的数组,其中的元素并没有实例化,依然是空的,所以还需要对每个元素都进行初始化(如果要调用的话)

 

13  Transaction rolled back because it has been marked as rollback-only

from:http://hi.baidu.com/zengqun89/item/226974356765c84d3075a1c7

今天调试的时候出现了错误:错误信息: Transaction rolled back because it has been marked as rollback-only ,经过排查后发现因为事务被提交了两次。如果以后出现了这样的错误,应该先看看自己的代码和相关的spring配置,看是否aop中已经配置了事务,但是又在代码中写了事务,这个最有可能导致这样的错误。

 

14 Can not find the tag library descriptor for "http://java.sun.com/jsp/jstl/

会报错,错误提示为: Can not find the tag library descriptor for "http://java.sun.com/jsp/jstl/core" 解决此问题的方法为以下: 在WEB-INF/lib里加入 jstl.jar standard.jar两个包即可解决这个问题

 

15Could not find action or result,There is no Action mapped for namespace / and action name hello_struts. - [unknown location]

 16java.sql.Timestamp cannot be cast to java.sql.Date

那么就把类型改过来

java.sql.Date--->java.sql.Timestamp
new java.sql.Timestamp(yourDate.getTime());

java.sql.Timestamp-->java.sql.Date
new java.sql.Date(yourTimestamp.getTime());


16其它

frorm:http://www.cnblogs.com/qinqinmeiren/archive/2010/10/14/2151702.html

ArithmeticException(除数为0的异常), BufferOverflowException(缓冲区上溢异常), BufferUnderflowException(缓冲区下溢异常), IndexOutOfBoundsException(出界异常), NullPointerException(空指针异常), EmptyStackException(空栈异常), IllegalArgumentException(不合法的参数异常), NegativeArraySizeException, NoSuchElementException, SecurityException, SystemException, UndeclaredThrowableException

17、浅谈java异常[Exception]

来自:http://www.cnblogs.com/focusj/archive/2011/12/26/2301524.html

 

一. 异常的定义

在《java编程思想》中这样定义 异常:阻止当前方法或作用域继续执行的问题。虽然java中有异常处理机制,但是要明确一点,决不应该用"正常"的态度来看待异常。绝对一点说异常就是某种意义上的错误,就是问题,它可能会导致程序失败。之所以java要提出异常处理机制,就是要告诉开发人员,你的程序出现了不正常的情况,请注意。

记得当初学习java的时候,异常总是搞不太清楚,不知道这个异常是什么意思,为什么会有这个机制?但是随着知识的积累逐渐也对异常有一点感觉了。举一个例子来说明一下异常的用途。

 

?
public class Calculator {
     public int devide( int num1, int num2) {
         //判断除数是否为0
         if (num2 == 0 ) {
             throw new IllegalArgumentException( "除数不能为零" );
         }
          
         return num1/num2;
     }
}

 

看一下这个类中关于除运算的方法,如果你是新手你可能会直接返回计算结果,根本不去考虑什么参数是否正确,是否合法(当然可以原谅,谁都是这样过来的)。但是我们应尽可能的考虑周全,把可能导致程序失败的"苗头"扼杀在摇篮中,所以进行参数的合法性检查就很有必要了。其中执行参数检查抛出来的那个参数非法异常,这就属于这个方法的不正常情况。正常情况下我们会正确的使用计算器,但是不排除粗心大意把除数赋值为0。如果你之前没有考虑到这种情况,并且恰巧用户数学基础不好,那么你完了。但是如果你之前考虑到了这种情况,那么很显然错误已在你的掌控之中。

 

二. 异常扫盲行动

 

今天和别人聊天时看到一个笑话:世界上最真情的相依,是你在try我在catch。无论你发神马脾气,我都默默承受,静静处理。 大多数新手对java异常的感觉就是:try...catch...。没错,这是用的最多的,也是最实用的。我的感觉就是:java异常是从"try...catch..."走来。

 

首先来熟悉一下java的异常体系:

 

Throwable 类是 Java 语言中所有错误或异常的超类(这就是一切皆可抛的东西)。它有两个子类:ErrorException

 

Error用于指示合理的应用程序不应该试图捕获的严重问题。这种情况是很大的问题,大到你不能处理了,所以听之任之就行了,你不用管它。比如说VirtualMachineError:当 Java 虚拟机崩溃或用尽了它继续操作所需的资源时,抛出该错误。好吧,就算这个异常的存在了,那么应该何时,如何处理它呢??交给JVM吧,没有比它更专业的了。

 

Exception它指出了合理的应用程序想要捕获的条件。Exception又分为两类:一种是CheckedException,一种是UncheckedException。这两种Exception的区别主要是CheckedException需要用try...catch...显示的捕获,而UncheckedException不需要捕获。通常UncheckedException又叫做RuntimeException。《effective java》指出:对于可恢复的条件使用被检查的异常(CheckedException),对于程序错误(言外之意不可恢复,大错已经酿成)使用运行时异常(RuntimeException)。

 

我们常见的RuntimeExcepitonIllegalArgumentException、IllegalStateExceptionNullPointerExceptionIndexOutOfBoundsException等等。对于那些CheckedException就不胜枚举了,我们在编写程序过程中try...catch...捕捉的异常都是CheckedExceptionio包中的IOException及其子类,这些都是CheckedException

 

 

 

三. 异常的使用

 

在异常的使用这一部分主要是演示代码,都是我们平常写代码的过程中会遇到的(当然只是一小部分),抛砖引玉吗!

 

1. 这个例子主要通过两个方法对比来演示一下有了异常以后代码的执行流程。 

 

?
public static void testException1() {
         int [] ints = new int [] { 1 , 2 , 3 , 4 };
         System.out.println( "异常出现前" );
         try {
             System.out.println(ints[ 4 ]);
             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.println( "异常出现前" );
         System.out.println(ints[ 4 ]);
         System.out.println( "我还有幸执行到吗" ); // 发生异常以后,他后面的代码不能被执行
     }

  

首先指出例子中的不足之处,IndexOutofBoundsException是一个非受检异常,所以不用try...catch...显示捕捉,但是我的目的是对同一个异常用不同的处理方式,看它会有什么不同的而结果(这里也就只能用它将就一下了)。异常出现时第一个方法只是跳出了try块,但是它后面的代码会照样执行的。但是第二种就不一样了直接跳出了方法,比较强硬。从第一个方法中我们看到,try...catch...是一种"事务性"的保障,它的目的是保证程序在异常的情况下运行完毕,同时它还会告知程序员程序中出错的详细信息(这种详细信息有时要依赖于程序员设计)。

2. 重新抛出异常

 

?
public class Rethrow {
     public static void readFile(String file) throws FileNotFoundException {
         try {
             BufferedInputStream 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 (FileNotFoundException e) {
             e.printStackTrace();
         }
     }
      
     public static void main(String[] args) {
         printFile( "D:/file" );
     }
}

 

  

异常的本意是好的,让我们试图修复程序,但是现实中我们修复的几率很小,我们很多时候就是用它来记录出错的信息。如果你厌倦了不停的处理异常,重新抛出异常对你来说可能是一个很好的解脱。原封不动的把这个异常抛给上一级,抛给调用这个方法的人,让他来费脑筋吧。这样看来,java异常(当然指的是受检异常)又给我们平添很多麻烦,尽管它的出发点是好的。

 

3. 异常链的使用及异常丢失

定义三个异常类:ExceptionA,ExceptionB,ExceptionC

 

?
public 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 NeverCaught {
     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.printStackTrace();
             }
     }
  
}
/*
exception.ExceptionC
at exception.NeverCaught.g(NeverCaught.java:12)
at exception.NeverCaught.main(NeverCaught.java:19)
*/

为什么只是打印出来了ExceptionC而没有打印出ExceptionB呢?这个还是自己分析一下吧!

上面的情况相当于少了一种异常,这在我们排错的过程中非常的不利。那我们遇到上面的情况应该怎么办呢?这就是异常链的用武之地:保存异常信息,在抛出另外一个异常的同时不丢失原来的异常。

 

?
public class NeverCaught {
     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.printStackTrace();
             }
     }
  
}
/*
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
*/

这个异常链的特性是所有异常均具备的,因为这个initCause()方法是从Throwable继承的。

4. 清理工作

清理工作对于我们来说是必不可少的,因为如果一些消耗资源的操作,比如IO,JDBC。如果我们用完以后没有及时正确的关闭,那后果会很严重,这意味着内存泄露。异常的出现要求我们必须设计一种机制不论什么情况下,资源都能及时正确的清理。这就是finally

 

?
public void readFile(String file) {
         BufferedReader reader = null ;
         try {
             reader = new BufferedReader( new InputStreamReader(
                     new FileInputStream(file)));
             // do some other work
         } catch (FileNotFoundException e) {
             e.printStackTrace();
         } finally {
             try {
                 reader.close();
             } catch (IOException e) {
                 e.printStackTrace();
             }
         }
     }

例子非常的简单,是一个读取文件的例子。这样的例子在JDBC操作中也非常的常见。(所以,我觉得对于资源的及时正确清理是一个程序员的基本素质之一。)

Try...finally结构也是保证资源正确关闭的一个手段。如果你不清楚代码执行过程中会发生什么异常情况会导致资源不能得到清理,那么你就用try对这段"可疑"代码进行包装,然后在finally中进行资源的清理。举一个例子:

 

?
public void readFile() {
         BufferedReader reader = null ;
         try {
             reader = new BufferedReader( new InputStreamReader(
                     new FileInputStream( "file" )));
             // do some other work
          
             //close reader
             reader.close();
         } catch (FileNotFoundException e) {
             e.printStackTrace();
         } catch (IOException e) {
             e.printStackTrace();
        
     }

 

我们注意一下这个方法和上一个方法的区别,下一个人可能习惯更好一点,及早的关闭reader。但是往往事与愿违,因为在reader.close()以前异常随时可能发生,这样的代码结构不能预防任何异常的出现。因为程序会在异常出现的地方跳出,后面的代码不能执行(这在上面应经用实例证明过)。这时我们就可以用try...finally来改造:

 

?
public void readFile() {
         BufferedReader reader = null ;
         try {
             try {
                 reader = new BufferedReader( new InputStreamReader(
                         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就是这么中规中矩)

再说一种情况,假如我想在构造方法中打开一个文件或者创建一个JDBC连接,因为我们要在其他的方法中使用这个资源,所以不能在构造方法中及早的将这个资源关闭。那我们是不是就没辙了呢?答案是否定的。看一下下面的例子:

 

?
public class ResourceInConstructor {
     BufferedReader reader = 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();
         }
     }
      
     public void dispose() {
         try {
             reader.close();
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
}

这一部分讲的多了一点,但是异常确实是看起来容易用起来难的东西呀,java中还是有好多的东西需要深挖的。

 

四. 异常的误用

对于异常的误用着实很常见,上一部分中已经列举了几个,大家仔细的看一下。下面再说两个其他的。

1. 用一个Exception来捕捉所有的异常,颇有"一夫当关万夫莫开"的气魄。不过这也是最傻的行为。

 

?
public void readFile(String file) {
         BufferedReader reader = null ;
         Connection conn = null ;
         try {
             reader = new BufferedReader( new InputStreamReader(
                     new FileInputStream(file)));
             // do some other work
              
             conn = DriverManager.getConnection( "" );
             //...
         } catch (Exception e) {
             e.printStackTrace();
         } finally {
             try {
                 reader.close();
                 conn.close();
             } catch (Exception e) {
                 e.printStackTrace();
             }
         }
     }

 

  

从异常角度来说这样严格的程序确实是万无一失,所有的异常都能捕获。但是站在编程人员的角度,万一这个程序出错了我们该如何分辨是到底是那引起的呢,IO还是JDBC...所以,这种写法很值得当做一个反例。大家不要以为这种做法很幼稚,傻子才会做。我在公司实习时确实看见了类似的情况:只不过是人家没有用Exception而是用了Throwable

2. 这里就不举例子了,上面的程序都是反例。异常是程序处理意外情况的机制,当程序发生意外时,我们需要尽可能多的得到意外的信息,包括发生的位置,描述,原因等等。这些都是我们解决问题的线索。但是上面的例子都只是简单的printStackTrace()。如果我们自己写代码,就要尽可能多的对这个异常进行描述。比如说为什么会出现这个异常,什么情况下会发生这个异常。如果传入方法的参数不正确,告知什么样的参数是合法的参数,或者给出一个sample

3. try block写的简短,不要所有的东西都扔在这里,我们尽可能的分析出到底哪几行程序可能出现异常,只是对可能出现异常的代码进行try。尽量为每一个异常写一个try...catch,避免异常丢失。在IO操作中,一个IOException也具有"一夫当关万夫莫开"的气魄。

五.总结

总结非常简单,不要为了使用异常而使用异常。异常是程序设计的一部分,对它的设计也要考究点。


 二 SVN

1、svn 提交抛异常:some of selected resources were not committed

【SVN】SVN错误[locked; try performing]的解决办法

from:http://blog.sina.com.cn/s/blog_57769b7b0101ac7p.html

用Eclipse的svn插件commit的时候,发生如下异常

Some of selected resources were not committed.
svn: Working copy 'C:\project\xxxxx\xxxxx-web\test'
locked; try performing 'cleanup'

 

于是,试着cleanup一下(team菜单下的clean up)
但clean up也发生异常

*** Cleanup
svn cleanup "C:\project\xxxxx\xxxxx-web\test"
svn: Error processing command 'modify-entry' in
'C:\project\xxxxx\xxxxx-web\test'
svn: Error modifying entry for 'spring'
svn: 'spring' is not under version control
*** Error (took 00:01.075)

 

找到这个test路径打开[.svn]文件夹,发现里面有[lock]和[log]文件
log文件内容

<modify-entry
    name="spring"
    working-size="working"/>

 

好了,问题明了。解决办法:

1.删除lock文件
2.删除log文件
3.clean up

 

 三 Tomcat启动


1、com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: Invalid byte 2 of 2-byte UTF-8 sequence.

from:http://blog.csdn.net/democreen/article/details/6696495

分析,这个问题的主要原因是xml文件中声明的编码与xml文件本身保存时的编码不一致。比如你的声明是

<?xml version="1.0" encoding="UTF-8"?>  

但是却以ANSI格式编码保存,尽管并没有乱码出现,但是xml解析器是无法解析的。
解决办法就是重新设置xml文件保存时的编码与声明的一致

2、Timeout waiting for Tomcat v6.0 Server @ localhost to start. Server did not start after 45s

具体现象就是eclipse在启动tomcat时, 会报错: “Timeout waiting for Tomcat v6.0 Server @ localhost to start. Server did not start after 45s” 的错误。 尤其是在debug时更加容易出现这个问题。 通过错误提示来看, 是因为tomcat启动时间超过了45m, 于是被终止了启动。出现这个问题,可能是应用程序比较庞大, 有很多启动加载项和初始化工作, 或者log太多。想着加大tomcat启动超时的时间, 却在我的eclipse3.3中一直没有找到相关项。 通过google还是找到了这个问题的解决办法,具体如下:在eclipse中找菜单 winodw -> preferences -> server -> 找 Server timeout delay 下拉列表项目。选择你想要的。我选择unlimited 让其不再有时间限制。就是说,服务启动多长时间都无所谓。问题就此解决。

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值