zoukankan      html  css  js  c++  java
  • 接口 类型转换 try-catch(学习笔记)


    (抽象类,接口)内容已经在前面的博客有记载http://www.cnblogs.com/tobecabbage/p/3460984.html  http://www.cnblogs.com/tobecabbage/p/3468115.html

    • 转换的说明

    -》隐式类型转换:正常的值类型的隐式转换,里氏转换原则,装箱

    double  dNum=123;

    -》强制类型转换:正常的值类型的强制转换,里氏转换原则,拆箱

    int num=(int)123.456;

    -》类型转型

    int  num=Convert.ToInt32("123");


    计算机只认识0和1,所以用二进制表示(两个位bit),8个bit表示一个字节

    int32 4个字节 0000 0000 0000 0000 0000 0000 0000 0000

    因这二进制不便于阅读,所以计算机用16进制描述数据。

    8位一个字节

    0000 0001  1 

    0000 0010  2

    0000 0011  3

    0000 0100  4

    0000 0101  5

    0000 0110  6

    0000 0111  7

    ....

    1111 1111  0-255共256个数字  恰好是16的平方

            二进制   16进制

       1000 8

       1001 9

       1010 a

         1011   b

       1100   c

         1101 d

             1110 e

       1111    f

    0001 0000    10


     单步调试到Main方法的最后一行,查看变量内存地址中数据

     

    double类型的数据可以除以0,得到正无穷大

    double bd=90.0000;
    Console.WriteLine(bd/0.0000000000);//结果为正无穷大

    里氏转换见前面的博客已有记载,简单解释概括为:子类的对象new sub()分配的内存空间地址偏移量比父类的对象New base()要大。所以一个父类的引用变量指向一个子类的对象是可以的,只是访问不到子类的数据而已(若想访问到子类对象的数据,需要重写父类的方法)。而一个父类的对象地址偏移量小,却用一个子类的引用变量指向,这就意味这可以用这个子类的引用变量反问到子类的数据,可是该子类引用变量指向的确实父类的对象,内存空间里根本没有子类的数据。这与子类引用变量能访问到子类的数据相矛盾()。

    里氏转换 base  b= new sub();     sub s=(sub)b;因为b本来指向的就是一个sub()对象,里面存有子类的数据,所以sub类型引用变量s能访问到sub对象的数据。转换陈功。里氏转换的存在的目的是为了实现多肽。


    装箱拆箱前面博客已有记


    • 异常是程序中运行时错误,它违反了一个系统的约束或应用程序约束,或出现了正常操作时未预料的情形。 

    Convert.ToInt32("123abc");//格式不正确

    Convert.ToInt32("12345678901234567890");//对于int32太大或太小

    写程序

    -》遇到程序怎么样让程序不挂起

    -》怎样抛出异常

    try语句

    如果程序没有提供处理异常的代码,系统会挂起这个程序。

    ♢try语句用来指明被正异常保护的代码块,并提供代码以处理异常。

    ♢catch字句部分含有一个或多个catch字句。,这些都是处理异常的代码块,它们也称为是异常的处理程序。

    ♢finally块含有在所有情况下都要被执行的代码,无论有没有异常发生。

    catch字句部分与finally字句部分必须至少有一个,如果两个都有,finally必须放在最后,即catch字句的后面

    处理异常的代码

    satic void Main(){

      int x=10;

      try{

        int y=0;

        x/y; 

      }

      catch{

        ...//处理异常的代码

        Console.WriteLine("Handling all exceptions - Keeping on Runing");

      }

    }

    这段代码产生以下消息。注意,除了输出消息,没有异常已经发生的迹象。

    Handling all exceptions-Keeping on Runing

    异常类

    有许多不同类型的异常可以在程序中发生,BCL定义了许多类,每一个类代表了一个指定的异常类型。当一个异常发生时,CLR:

    ♢创建该类型的异常对象;

    ♢寻找适当的catch字句以处理它。

    所有的异常都从根本上派生自System.Exception类。

    System.Exception:所以异常类的基类

      -》SystemException:所有预定义系统异常的基类。IndexOfRangeException NullReference IOException

      -》ApplicationException:所有致命的、应用程序定义的异常的基类。

    异常对象含有只读属性,带有导致该异常的信息。

      属性       类型     描述

      Message string 这个属性含有解释异常的原因的消息

       StackTrace   string  这个属性含有描述异常发生在何处的信息

         InnerException  Exception 如果当前异常是由另一个异常引起的,这个异常包含前一个异常的引用

         HelpLink         string       这个属性可以被应用程序定义的异常设置,为异常原因信息提供URN或URL

         Source            string       如果没有被应用程序定义的异常设定,那么这个属性含有异常起源所在的程序集的名称。

    Catch字句的三种形式

    catch{

      Statements   一般catch字句,在catch关键字之后没有参数列表,匹配try块中引起的任何类型的异常。

    }

    catch(ExceptionType){

     Statements  特定catch字句 带有异常类的名称作为参数 匹配任何该类型的异常

    }

    catch(ExceptionType Exception){

      Statements    带对象的的特定Catch字句,在异常类名称之后包括一个标识符,该标识符在catch字句块中相当于一个本地变量,并被称为异常变量

    }                     异常变量应用异常对象,并能用于访问该变量的信息

    一般catch字句能接受任何异常,但不能确定引发异常的类型。

    特定catch字句形式把一个异常类的名作为参数,它匹配该指定类或派生自它的异常类的异常。

    带对象的特定catch字句提供最多的关于异常的信息。它匹配指定类的异常,或派生自它的异常类的异常。它还给出一个异常实例,称为异常变量,它是一个对CLR创建的异常对象的引用。

     使用特定Catch字句的示例

    int x=0;

    try{

    int y=0;

    x/y;

    }

    catch(DivideByException){

    ...

    Console.WritelLine("Handling an exception");

    }

    int x=0;

    try{

    int y=0;

    x/y;

    }

    catch(DividedByException e){

      Console.WriteLine("Messsage:{0},e.Message);

      Console.WriteLine("Source:{0},e.Source);

      Console.WriteLine("Stack:{0},e.StackTrace);

    }

    Catch 字句块目的是允许你以一种优雅的方式处理异常。

    catch字句块可以包含多个catch字句,特定catch 字句允许多于一个,一般catch字句只允许一个。

    catch字句的排序有两个重要的规则

    ♢特定catch字句必须以一种顺序排序,最明确的异常类型第一,直到最普通的类型,例如,如果声明一个派生自NullReferenceException的异常类,那么派生自异常类型的Catch子句应该被列在NullReferenceException的catch字句之前。

    ♢如果有一个catch子句,它必须是最后一个,它必须在所有特定的catch子句之后,使用一般catch子句一般是不好的,应该尽可能使用特定的catch子句。一般catch子句通过让程序继续执行隐藏错误。

    • 抛出异常

    func1(){func2();}

    func2(){func3();}

    func3(){func4();}

    如果func4()里面出现异常,首先在func4()里查找是否有匹配的异常处理的代码,若没有,继续往上抛异常,在func3()里面找匹配的代码块...若一直没找找到,就抛给Main()方法,若还是找不到匹配的异常处理代码,继续抛给CLR,继续抛给操作系统。

      class Program
        {
            static void Main(string[] args)
            {
                Myclass MCls = new Myclass();
                try
                {
                    MCls.A();
                }
                catch (System.DivideByZeroException)
                {
                    Console.WriteLine("catch cause in main()");
                }
                finally
                {
                    Console.WriteLine("finally cause in main()");
                }
                Console.WriteLine("After try statement in Main.");
                Console.WriteLine("     ---keep running");
                Console.ReadKey();
            }
        }
        class Myclass
        {
            public void A()
            {
                try
                {
                    B();
                }
                catch (System.NullReferenceException)
                {
                    Console.WriteLine("catch clause in A()");
                }
                finally
                {
                    Console.WriteLine("finally clause in A()");
                }
            }
            void B()
            {
                int x = 0, y = 0;
                try
                {
                    x/=y;
                }
                catch (System.IndexOutOfRangeException)
                {
                    Console.WriteLine("catch clause in B()");
                }
                finally
                {
                    Console.WriteLine("finally clause in B()");
                }
            }
        }

    程序运行结果

    图解:

     抛出异常

    throw new Exception();

    •  异常的性能问题
     static void Main(string[] args)
            {
                Stopwatch s = new Stopwatch();
                s.Start();
                int sum = 0;
                for (int i = 0; i < 100;i++ )
                {
                    sum += i;
                }
                s.Stop();
                Console.WriteLine(s.Elapsed);//结果为00:00:00:0.0000079
                Console.ReadKey();
            }
    static void Main(string[] args)
            {
                Stopwatch s = new Stopwatch();
                s.Start();
                int sum = 0;
                for (int i = 0; i < 100;i++ )
                {
                   try
                   {
                       throw new Exception("错误");
                   }
                   catch (System.Exception ex)
                   {
                       
                   }
                }
                s.Stop();
                Console.WriteLine(s.Elapsed);//结果为00:00:01:2128577
                Console.ReadKey();
            }


    从以上代码中可以看出,try{}catch(){}会导致运行速度非常慢。所以建议慎用try-catch字句,尽可能用if-esle。若是涉及到访问本地文件,没有权限,或是访问数据库,网忽然断掉的异常采用try-catch

                                                                                                                                                                                                                                                 

  • 相关阅读:
    Python读取ini配置文件封装方法
    Python对Selenium调用浏览器进行封装包括启用无头浏览器,及对应的浏览器配置文件
    windows下 apache 二级域名相关配置
    Incorrect integer value: '' for column 'id' at row 1
    [Effective Java 读书笔记] 第二章 创建和销毁对象 第三 四条
    [Effective Java 读书笔记] 第二章 创建和销毁对象 第二条
    [Effective Java 读书笔记] 第二章 创建和销毁对象 第一条
    JAVA ReentrantLock的使用
    Thread类的interrupted方法和isInterrupted方法的区别
    [转]java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?
  • 原文地址:https://www.cnblogs.com/tobecabbage/p/3528076.html
Copyright © 2011-2022 走看看