zoukankan      html  css  js  c++  java
  • 20145312 《Java程序设计》第五周学习总结

    20145312 《Java程序设计》第五周学习总结

    学习笔记

    Chapter8 异常处理

    8.1语法与继承架构

    1.Java中的错误以对象方式呈现,只要捕捉包装错误的对象,就可以针对该错误进行处理。

    8.1.1 使用try、catch

    1.求平均值为例。
    代码如下:

    import java.util.Scanner;
    public class Average {
        public static void main(String[] args){
            Scanner console=new Scanner(System.in);
            double sum=0;
            int count=0;
            while (true){
                int number=console.nextInt() ;
                if(number==0){
                    break;
                }
                sum+=number;
                count++;
            }
            System.out.printf("平均%.2f%n",sum/count);
        }
    }
    

    结果如下:

    12
    34
    56
    78
    0
    平均45.00
    

    2.如果输入错误,会被打包成对象,可以尝试try()捕捉catch()代表错误的对象后做一些处理。
    代码如下:

    import java.util.* ;
    public class Average2 {
        public static void main(String[] args){
            try{
                Scanner console=new Scanner(System.in);
                double sum=0;
                int count=0;
                while (true) {
                    int number = console.nextInt();
                    if (number == 0) {
                        break;
                    }
                    sum += number;
                    count++;
                }
                System.out.printf("平均%.2f%n",sum/count);
            }catch (InputMismatchException ex){
                System.out.println("必须输入整数");
            }
        }
    }
    /*
    JVM尝试执行try区块的代码,如果有错,执行流程跳过错误发生点,然后比较catch区块中声明的类型,是否符合错误对象类型,如果是就执行catch区块。
     */
    

    结果如下:

    12
    34
    5o
    必须输入整数
    

    3.有时错误可以在捕捉处理之后,尝试恢复程序。
    代码如下:

    import java.util.*;
    public class Average3 {
        public static void main(String[] args){
            Scanner console=new Scanner(System.in);
            double sum=0;
            int count=0;
            while (true) {
                try {
                    int number = console.nextInt();
                    if (number == 0) {
                        break;
                    }
                    sum += number;
                    count++;
                } catch (InputMismatchException ex) {
                    System.out.printf("略过非整数输入:%s%n", console.next());
                }
            }
            System.out.printf("平均%.2f%n",sum/count);
        }
    }
    /*
    如果nextInt()发生了InputMismatchException错误,流程跳至catch区块执行,并继续执行循环流程。
     */
    

    结果如下:

    12
    34
    56
    7o
    略过非整数输入:7o
    0
    平均34.00
    
    8.1.2 异常继承架构

    1.错误会被包装成对象,且可抛出。
    2.设计错误对象继承自java.lang.Throwable类,Throwable定义了取得错误信息、堆栈追踪等方法,它有两个子类:java.lang.Errow与java.lang.Exception。
    代码如下:

    import java.util.Scanner;
    public class Average4 {
        public static void main(String[] args){
            double sum=0;
            int count=0;
            while (true) {
                int number = nextInt();
                if (number == 0) {
                    break;
                }
                sum += number;
                count++;
            }
            System.out.printf("平均%.2f%n",sum/count);
        }
        static Scanner console=new Scanner(System.in);
        static int nextInt() {
            String input = console.next();
            while (!input.matches("\d*"))//规则表示式,检查字符串中的字符是否是数字
            {
                System.out.println("请输入数字");
                input = console.next();
            }
            return Integer.parseInt(input);
        }
    }
    

    结果如下:

    12
    34
    5o
    请输入数字
    78
    0
    平均41.33
    
    8.1.3 要抓还是要抛

    1.实际异常发生时,可使用try,catch处理当时环境可进行的异常处理,当时环境下无法决定如何处理的部分,可以抛出用调用方法的客户端处理。
    代码如下:

    import java.io.* ;
    import java.util.Scanner;
    public class FileUtil {
        public static String readFile(String name) throws FileNotFoundException{//声明方法中会抛出异常
            StringBuilder text=new StringBuilder();
            try{
                Scanner console=new Scanner(new FileInputStream(name));
                while(console.hasNext()){
                    text.append(console.nextLine())
                            .append('
    ');
                }
            }catch(FileNotFoundException ex){
                ex.printStackTrace();
                throw ex;//执行时抛出异常
            }
            return text.toString();
        }
    }
    

    2.如果抛出的异常是非受检异常,表示你认为客户端调用方法的时机出错了,此时不用throw声明。

    8.1.4 认识堆栈追踪

    1.在多重方法调用下,异常发生点可能是在某个方法中,若想得知异常发生的根源,以及多重方法调用下异常的堆栈传播,可以利用异常对象自动收集的堆栈追踪来取的相关信息。
    2.查看堆栈追踪最简单的方法,就是直接调用异常对象的printStackTrace()。
    代码如下:

    public class StackTraceDemo {
        public static void main(String[] args){
            try{
                c();
            }catch(NullPointerException ex){
                ex.printStackTrace() ;
            }
        }
        static void c(){
            b();
        }
        static void b(){
            a();
        }
        static String a(){
            String text=null;
            return text.toUpperCase() ;
        }
    }
    /*
    c()方法调用b()方法,b()方法调用a()方法,而a()方法中会因text参考至null,而后试图调用toUpperCase引发NullPointerException。
     */
    

    结果如下:

    java.lang.NullPointerException
    	at TryCatch.StackTraceDemo.a(StackTraceDemo.java:22)
    	at TryCatch.StackTraceDemo.b(StackTraceDemo.java:18)
    	at TryCatch.StackTraceDemo.c(StackTraceDemo.java:15)
    	at TryCatch.StackTraceDemo.main(StackTraceDemo.java:9)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:498)
    	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
    

    3.在使用throw重抛异常时,异常的追踪堆栈起点,仍是异常的发生根源,而不是重抛异常的地方。
    代码如下:

    public class StackTraceDemo2 {
        public static void main(String[] args){
            try{
                c();
            }catch(NullPointerException ex){
                ex.printStackTrace();
            }
        }
        static void c(){
            try{
                b();
            }catch(NullPointerException ex){
                ex.printStackTrace();
                throw ex;
            }
        }
        static void b(){
            a();
        }
        static String a(){
            String text=null;
            return text.toUpperCase() ;
        }
    }
    

    结果如下:

    java.lang.NullPointerException
    	at TryCatch.StackTraceDemo2.a(StackTraceDemo2.java:27)
    	at TryCatch.StackTraceDemo2.b(StackTraceDemo2.java:23)
    	at TryCatch.StackTraceDemo2.c(StackTraceDemo2.java:16)
    	at TryCatch.StackTraceDemo2.main(StackTraceDemo2.java:9)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:498)
    	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
    java.lang.NullPointerException
    	at TryCatch.StackTraceDemo2.a(StackTraceDemo2.java:27)
    	at TryCatch.StackTraceDemo2.b(StackTraceDemo2.java:23)
    	at TryCatch.StackTraceDemo2.c(StackTraceDemo2.java:16)
    	at TryCatch.StackTraceDemo2.main(StackTraceDemo2.java:9)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:498)
    	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
    

    4.如果想要让异常堆栈起点为重抛异常的地方,可以的使用fillInStackTrace()方法,这个方法会重新装填异常堆栈,将起点设为重抛异常的地方,并返回Throwable对象。
    代码如下:

    public class StackTraceDemo3 {
        public static void main(String[] args){
            try{
                c();
            }catch(NullPointerException ex){
                ex.printStackTrace();
            }
        }
        static void c(){
            try{
                b();
            }catch(NullPointerException ex){
                ex.printStackTrace();
                Throwable t=ex.fillInStackTrace() ;
                throw (NullPointerException ) t;
            }
        }
        static void b(){
            a();
        }
        static String a(){
            String text=null;
            return text.toUpperCase() ;
        }
    }
    

    结果如下:

    java.lang.NullPointerException
    	at TryCatch.StackTraceDemo3.a(StackTraceDemo3.java:28)
    	at TryCatch.StackTraceDemo3.b(StackTraceDemo3.java:24)
    	at TryCatch.StackTraceDemo3.c(StackTraceDemo3.java:16)
    	at TryCatch.StackTraceDemo3.main(StackTraceDemo3.java:9)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:498)
    	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
    java.lang.NullPointerException
    	at TryCatch.StackTraceDemo3.c(StackTraceDemo3.java:19)
    	at TryCatch.StackTraceDemo3.main(StackTraceDemo3.java:9)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:498)
    	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
    
    8.1.6关于assert
    1. 两种语法:
      Assert Boolean_expresssion;
      Assert Boolean_expresssion:detail_expression;

    2. 使用assert做关键词,默认执行时不启动断言检查。

    3.何时使用断言:
    断言客户端调用方法前,已经准备好某些前置条件(通常在private方法之中)。
    断言客户端调用方法后,具有方法承诺的结果。
    断言对象某个时间点下的状态。
    使用断言取代批注。
    断言程序流程中绝对不会执行到的程序代码部分。

    8.2 异常与资源管理

    8.2.1 使用finally

    1.try、catch语法可以搭配finally,执行关闭资源的动作。
    代码如下:

    import java.io.* ;
    import java.util.Scanner;
    public class FileUtil {
        public static String readFile(String name) throws FileNotFoundException{
            StringBuilder text=new StringBuilder();
            Scanner console=null;
            try{
                console=new Scanner(new FileInputStream(name));
                while(console.hasNext()){
                    text.append(console.nextLine())
                            .append('
    ');
                }
            }finally{
                if(console !=null){
                    console.close();
                }
            }
            return text.toString();
        }
    }
    

    2.如果程序撰写的流程中先return了,而且也有finally区块,那finally区块会先执行完后,再将值返回。
    代码如下:

    public class FinallyDemo {
        public static void main(String[] args){
            System.out.println(test(true));
        }
        static int test(boolean flag){
            try{
                if(flag){
                    return 1;
                }
            }finally{
                System.out.println("finally...");
            }
            return 0;
        }
    }
    

    结果如下:

    finally...
    1
    
    8.2.2 自动尝试关闭资源

    1.JDK7之后,新增了尝试关闭资源(Try-With-Resources)语法。
    代码如下:

    import java.io.FileInputStream ;
    import java.io.FileNotFoundException ;            
    import java.util.Scanner ;
    public class FileUtil2{
        public static String readFile(String name) throws FileNotFoundException{
            StringBuilder text=new StringBuilder();
            try( Scanner console=new Scanner(new FileInputStream(name))){
                while (console.hasNext() ){
                    text.append(console.nextLine())
                            .append('
    ');
                }
            }
            return text.toString();
        }
    }
    
    8.2.3 java.lang.AutoCloseable接口
    1. AutoCloseable是JDK7新增的接口,仅定义了close()方法。

    2.只要操作AutoCloseable接口,就可以套用至尝试关闭资源语法。
    代码如下:

    public class AutoCloseableDemo {
        public static void main(String[] args){
            try(Resource res=new Resource()){
                res.doSome();
            }catch(Exception ex){
                ex.printStackTrace() ;
            }
        }
    }
    class Resource implements AutoCloseable {
        void doSome(){
            System.out.println("做一些事");
        }
        @Override
        public void close() throws Exception {
            System.out.println("资源被关闭");
        }
    }
    

    结果如下:

    做一些事
    资源被关闭
    

    2.尝试关闭资源语法可以关闭两个以上的对象资源,中间以分号隔开。
    代码如下:

    import static java.lang.System.out;
    public class AutoCloseableDemo2 {
        public static void main(String[] args){
            try(ResourceSome some=new ResourceSome();
                ResourceOther other=new ResourceOther()){
                    some.doSome();
                    other.doOther();
                }catch(Exception ex){
                ex.printStackTrace() ;
                }
        }
    }
    class ResourceSome implements AutoCloseable{
        void doSome(){
            System.out.println("做一些事");
        }
        @Override
        public void close() throws Exception {
            System.out.println("资源some被关闭");
        }
    }
    class ResourceOther implements AutoCloseable {
        void doOther() {
            System.out.println("做其他事");
        }
    
        @Override
        public void close() throws Exception {
            System.out.println("资源other被关闭");
        }
    }
    

    结果如下:

    做一些事
    做其他事
    资源other被关闭
    资源some被关闭
    

    Chapter 9 Collection与Map

    9.1 使用Collection收集对象

    9.1.1 认识Collection架构

    1.目的:针对收集对象的需求。

    9.1.2 具有索引的List

    1.List是一种Collection,作用是收集对象。
    代码如下:

    import java.util.* ;
    import java.util.ArrayList;
    
    import static java.lang.System.out;
    public class Guest {
        public static void main(String[] args){
            List names=new ArrayList();
            collectNameTo(names );
            out.print("访客名单:");
            printUpperCase(names);
        }
        static void collectNameTo(List names){
            Scanner console=new Scanner(System.in);
            while(true){
                out.print("访客名单:");
                String name=console.nextLine();
                if(name.equals("quit")){
                    break;
                }
                names.add(name);
            }
        }
        static void printUpperCase(List names){
            for(int i=0;i<names.size();i++){
                String name=(String)names.get(i);
                out.println(name.toUpperCase() );
            }
        }
    }
    

    结果如下:

    访客名单:张三
    访客名单:李四
    访客名单:王二麻子
    访客名单:quit
    访客名单:张三
    李四
    王二麻子
    

    2.ArrayList特性
    有数组排序需求时,用ArrayList有较快的速度表现。
    需要调整索引顺序时,用ArrayList有较差的表现。
    ArrayList有个可指定容量的构造函数。
    3.LinkedList特性
    LinkedList在操作接口时,采用了Link结构。
    代码如下:

    public class SimpleLinkedList {
        private class Node{
            Node(Object o){
                this.o=o;
            }
            Object o;
            Node next;
        }
        private Node first;
        public void add(Object elem){
            Node node=new Node(elem);
            if(first==null){
                first=node;
            }
            else{
                append(node);
            }
        }
        private void append(Node node){
            Node last=first;
            while(last.next !=null){
                last=last.next;
            }
            last.next=node;
        }
        public int size(){
            int count=0;
            Node last=first;
            while(last !=null){
                last=last.next;
                count++;
            }
            return count;
        }
        public Object get(int index){
            checkSize(index);
            return findElemOf(index);
        }
        private void checkSize(int index) throws IndexOutOfBoundsException {
            int size=size();
            if(index>=size){
                throw new IndexOutOfBoundsException(
                        String.format("Index:%d,Size:%d",index,size);
            }
        }
        private Object findElemOf(int index){
            int count=0;
            Node last=first;
            while(count<index){
                last=last.next;
                count++;
            }
            return last.elem;
        }
    }
    
    9.1.3 内容不重复的Set

    1.使用Set接口的操作对象,可以在手机对象过程中,遇到相同对象,可不重复收集。
    代码如下:

    import java.util.* ;
    public class WordCount {
        public static void main(String[] args){
            Scanner console=new Scanner(System.in);
            System.out.println("请输入英文:");
            Set words=tokenSet(console.nextLine());
            System.out.printf("不重复单字有:%d个:%s%n",words.size(),words);
        }
        static Set tokenSet (String line){
            String[] tokens=line.split(" ");
            return new HashSet(Arrays.asList(tokens));
        }
    }
    

    结果如下:

    请输入英文:
    This is a dog that is a cat where is the student
    不重复单字有:9个:[a, student, is, the, that, cat, This, where, dog]
    

    2.若操作了hashCode()与equals()方法,则重复的Student不会被收集。

    9.1.4 支持队列操作的Queue

    1.作用:使用Queue接口的操作,收集对象时以队列方式,收集的对象加入至末尾端,取得对象时从前段。
    2.建议使用offer()、poll()、peak()等方法。
    代码如下:

    import java.util.*;
    
    interface Request 
    {
        void execute();
    }
    
    public class RequestQueue
    {        
        public static void main(String[] args)
       {
            Queue requests = new LinkedList();
            offerRequestTo(requests);
            process(requests);
        }
    
        static void offerRequestTo(Queue requests)
        {
            for (int i = 1; i < 6; i++) 
            {
                Request request = new Request()
                {
                    public void execute() 
                    {
                        System.out.printf("處理資料 %f%n", Math.random());
                    }
                };
                requests.offer(request);
            }
        }
    
        static void process(Queue requests) 
        {
            while(requests.peek() != null)
            {
                Request request = (Request) requests.poll();
                request.execute();
            }
        }
    }
    
    9.1.5 使用泛型

    1.作用:在设计API时可以指定类或方法支持泛型,而使用API的客户端在语法上会更为简洁,并得到编译时期检查。
    代码如下:

    import java.util.Arrays;
    
    public class ArrayList<E>
    {
         Object[] elems;
        private int next;
    
       public ArrayList(int capacity)
       {
            elems = new Object[capacity];
       }        
    
       public ArrayList()
       {
            this(16);
       }
    
       public void add(E e)
       {
            if(next == elems.length) 
            {
                elems = Arrays.copyOf(elems, elems.length * 2);
            }
            elems[next++] = e;
       }
    
       public E get(int index)
       {
            return (E) elems[index];
       }
    
       public int size()
       {
            return next;
       }
    }
    
    9.1.6 简介Lambda表达式

    1.相对于匿名类语法来说,Lambda表达式的语法省略了接口类型与方法名称,->左边是参数列,而右边是方法本体。
    2.在Lambda表达式中使用区块时,如果方法必须有返回值,在区块中就必须使用return。

    9.1.7 Interable与Iterator

    1.interator()方法提升至新的java.util.Iterable父接口。
    2.Collections的sort()方法要求被排序的对象必须java.lang.Comparable接口,这个接口有个compareTo()方法必须返回大于0、等于0或小于0的数。

    9.1.8 Comparable与Comparator

    1.Collections的sort()方法有另一个重载版本,java.util.Comparator接口的操作对象,如果使用这个版本,排序方式将根据Comparator的compare()定义来决定。
    代码如下:

    import java.util.*;
    
    class StringComparator implements Comparator<String> 
    {        
        @Override
        public int compare(String s1, String s2)
        {
            return -s1.compareTo(s2);
        }
    }
    
    public class Sort5
    {
        public static void main(String[] args) 
        {
            List<String> words = Arrays.asList("B", "X", "A", "M", "F", "W", "O");
            Collections.sort(words, new StringComparator());
           System.out.println(words);
       }
    }
    

    9.2 键值对应的Map

    9.2.1 常用Map操作类

    1.若要根据某个键来取得对应的值,可以事先利用java.util.Map接口的操作对象来建立键值对应数据,之后若要取得值,只要用对应的键就可以迅速取得。常用的Map操作类为java.util.HashMap与java.util.TreeMap,其继承自抽象类java.util.AbstractMap。

    2.Map也支持泛型语法,如使用HashMap的范例。

    代码如下:

    import java.util.*;
    import static java.lang.System.out;
    
    public class Messages 
    {
        public static void main(String[] args) 
        {
            Map<String, String> messages = new HashMap<>();
            messages.put("Justin", "Hello!Justin的訊息!");
            messages.put("Monica", "給Monica的悄悄話!");
            messages.put("Irene", "Irene的可愛貓喵喵叫!");
    
            Scanner console = new Scanner(System.in);
           out.print("取得誰的訊息:");
            String message = messages.get(console.nextLine());
            out.println(message);
            out.println(messages);
        }
    }
    
    1. 如果使用TreeMap建立键值对应,则键的部分则会排序,条件是作为键的对象必须操作Comparable接口,或者是在创建TreeMap时指定操作Comparator接口的对象。

    代码如下:

    import java.util.*;
    
    public class Messages2 
    {
        public static void main(String[] args) 
        {
            Map<String, String> messages = new TreeMap<>(); 
            messages.put("Justin", "Hello!Justin的訊息!");
            messages.put("Monica", "給Monica的悄悄話!");
            messages.put("Irene", "Irene的可愛貓喵喵叫!");
            System.out.println(messages);
        }        
    }
    
    9.2.2 访问Map键值

    1.如果想取得Map中所有的键,可以调用Map的keySet()返回Set对象。由于键是不重复的,所以用Set操作返回是理所当然的做法,如果想取得Map中所有的值,则可以使用values()返回Collection对象。

    代码如下:

    import java.util.*;
    import static java.lang.System.out;
    
    public class MapKeyValue 
    {
        public static void main(String[] args)
        {               
            Map<String, String> map = new HashMap<>();
            map.put("one", "一");
            map.put("two", "二");
            map.put("three", "三");
    
            out.println("顯示鍵");
            map.keySet().forEach(key -> out.println(key));
    
            out.println("顯示值");
            map.values().forEach(key -> out.println(key));
        }
    }
    

    教材学习中的问题和解决过程

    1.问题1:

    在看书时不知道Error与Exception的区别。

    解决过程:
    Exception或其子类实例代表程序设计本身的错误,所以通常称错误处理为异常处理(Exception Handling)。

    Error与其子类实例代表严重系统错误,如硬件层面错误、JVM错误或内存不足等问题,虽然也可以使用try、catch来处理Error对象,但并不建议,发生严重系统错误时,Java应用程序本身是无力回复的。

    代码调试中的问题和解决过程

    1.问题:
    在练习书P236的代码时,提示声明throw某些异常。
    解决过程:
    在仔细研读书后我看到书上提出了一些方法:
    如果使用继承时,父类某个方法声明throws异常,子类重新定义该方法时可以:
    不声明throws任何异常。
    throws父类该方法中声明的某些异常。
    throws父类该方法中声明异常的子类。
    但是不可以:
    throws父类方法中未声明的其他异常。
    throws父类该方法中声明异常的父类。
    其他(感悟、思考等,可选)
    本周学习了第八、第九章,开始接触了各种类、接口、方法、行为,经常分不清楚,使用时分不清楚区别,所以我就边看书边打代码边总结知识点,这样能增加记忆,看到后面忘了前面的内容时就可以看知识点再记忆一遍。这周我学习Java的时间很集中,这样短时间内汲取了大量的知识,有了连贯性,认识的更全面。

    托管代码截图



    学习进度条

    参考资料

  • 相关阅读:
    easyUI日期框,默认显示今天,今天以后的日期不能选
    vue实现下拉框全选和输入匹配
    【转载】CSS flex属性深入理解
    ES6学习之二
    Centos7(Firewall)防火墙命令
    DeDeCMS模板标签(2)
    DeDeCMS模板标签(1)
    常用js正则表达式大全
    linux yum 命令
    Linux软链接和硬链接
  • 原文地址:https://www.cnblogs.com/yx20145312/p/5351104.html
Copyright © 2011-2022 走看看