枚举类Enumeration

1)枚举对应英文(enumeration,简写enum)

2)枚举是一组常量的集合

3)可以理解为:枚举属于一种特殊的类,里面只包含一组 有限的 特定的 对象

1、自定义类实现枚举

  1. 不需要提供setXxx方法,因为枚举对象值通常为只读

  2. 对枚举对象/属性使用final+static修饰,实现底层优化(类不用加载)

  3. 枚举对象名通常使用全部大写,常量的命名规范

  4. 枚举对象根据需要,也可以有多个属性

public class Enumeration02 {public static void main(String[] args) {System.out.println(Season.AUTUMN);System.out.println(Season.SPRING);}
}//演示自定义枚举实现
class Season {private String name;private String desc; //描述//定义了四个对象//public final static:类不用被加载,在外部其他类可以直接调用自定义枚举public final static Season SPRING = new Season("春天","温暖");//多个属性(2个)public final static Season SUMMER = new Season("夏天","炎热");public final static Season AUTUMN = new Season("秋天","凉爽");public final static Season WINTER = new Season("冬天","寒冷");//1. 构造器私有化-》防止直接new//2. 去掉set相关方法-》防止属性被修改(只读不能写)//3. 在Season内部,直接创建固定的对象private Season(String name, String desc){this.name = name;this.desc = desc;}@Overridepublic String toString() {return "Season{" +"name='" + name + '\'' +", desc='" + desc + '\'' +'}';}
}

2、enum关键字实现枚举

1)使用注意事项

  1. 使用关键字enum替代class

  2. SPRING(“春天”,“温暖”); ==> 常量名(实参列表) =》根据实参列表判断调用的是哪个构造器

  3. 如果有多个常量(对象),使用,号间隔。最后一个用;号结束

  4. 如果使用enum来实现枚举,要求将定义常量对象写在类体的最前面

  5. 当使用enum关键字开发一个枚举类时,默认会继承Enum类(用javap反编译证明),并且是一个final类

  6. enum后不能再继承其他类(不能有extends关键字),因为底层隐式继承了Enum类

  7. 如果使用无参构造器创建枚举对象,则实参列表和小括号都可以省略

public class Enumeration03 {public static void main(String[] args) {System.out.println(Season2.AUTUMN);System.out.println(Season2.SPRING);}
}//使用enum关键字来实现枚举类
enum Season2 {//使用enum来实现枚举类//1. 使用关键字enum替代class//2. SPRING("春天","温暖"); ==> 常量名(实参列表)//3. 如果有多个常量(对象),使用,号间隔。最后一个用;号结束//4. 如果使用enum来实现枚举,要求将定义常量对象写在类体的最前面SPRING("春天","温暖"),SUMMER("夏天","炎热"),AUTUMN("秋天","凉爽"),WINTER("冬天","寒冷"),OTHER(); //调用的无参构造器,还可以直接简化成OTHERprivate String name;private String desc; //描述private Season2(){ //无参构造器}private Season2(String name, String desc){this.name = name;this.desc = desc;}public String getName() {return name;}public String getDesc() {return desc;}@Overridepublic String toString() {return "Season{" +"name='" + name + '\'' +", desc='" + desc + '\'' +'}';}
}

2)enum常用方法说明

说明:使用enum时,会隐式继承Enum类,这样我们可以使用Enum类的相关方法

public class EnumMethod {public static void main(String[] args) {//使用Season2 枚举类来演示(只有春夏秋冬四个枚举)Season2 autumn = Season2.AUTUMN;//【对象调用】name:输出枚举对象的名称System.out.println(autumn.name() + "\n"); //AUTUMN//【对象调用】ordinal: 输出该美剧对象的次序/编号(从0开始编号)System.out.println(autumn.ordinal()+ "\n"); //2//【类调用】values: 返回枚举数组,包含定义的所有枚举对象Season2[] values = Season2.values();for (Season2 season : values) {System.out.println(season);}System.out.println();//【类调用】valueOf: 将字符串转换成枚举对象,要求字符串必须为已有的常量名,否则报异常//功能:根据枚举名找到枚举,获得完整的枚举(包括枚举类属性)Season2 autumn1 = Season2.valueOf("AUTUMN");System.out.println("autumn1 = " + autumn1);System.out.println(autumn == autumn1); //true//compareTo:比较两个枚举常量,比较的是编号,①当==0,编号相等 ②当<0,前面的编号比后面的编号小//底层:return self.ordinal - other.ordinal;//Season2.AUTUMN - Season2.SUMMER编号System.out.println(Season2.AUTUMN.compareTo(Season2.SUMMER)); //1//toString:Enum类已经重写过,返回的是当前对象的名字(枚举名),如果自己再在枚举类中重写,则调用自己写的toString方法System.out.println(autumn);}
}

3)课堂练习

第一题

Enum的toString方法返回name,就是枚举的名字

输出:
BOY
true


第二题

public class Test {public static void main(String[] args) {Week[] weeks = Week.values();for(Week week : weeks){System.out.println(week);}}
}enum Week {MONDAY("星期一"),TUESDAY("星期二"),WEDNSDAY("星期三"),THURSDAY("星期四"),FRIDAY("星期五"),SATURDAY("星期六"),SUNDAY("星期日");private String desc;private Week(String desc){this.desc = desc;}@Overridepublic String toString() {return desc;}
}

4)enum实现接口

枚举和普通类一样,可以实现接口,如下形式:

enum 类名 implements 接口1,接口2{}

使用实现接口的方法:枚举类名.枚举名.方法名()

public class Test {public static void main(String[] args) {Music.CLASSICMUSIC.playing(); //使用实现接口的方法,枚举类名.枚举名.方法名()}
}interface IAA {public void playing();
}
enum Music implements IAA{CLASSICMUSIC;@Overridepublic void playing() {System.out.println("播放音乐...");}
}

注解Annotation

1、JDK内置的基本注解类型

1)@Override

限定某个方法,是重写父类方法。该注解只能用于方法

功能:语法校验


如果写了@Override,编译器就会去检查该方法是否真的重写了父类的方法。

如果的确重写了,则编译通过

如果没有构成重写,则编译错误


@Override定义

@interface:表示一个注解类

@Target:可以修饰的类型,这里只能修饰METHOD方法

@Target是修饰注解的注解 ==》元注解

2)@Deprecated

用于表示某个程序元素已过时

功能:做一个过渡,版本升级时的兼容过渡

3)@SuppressWarnings

抑制编译器警告

功能:当我们不希望看到警告信息时,可以使用SuppressWarnings抑制警告信息

用法:

@SuppressWarnings({""})

{""}中,可以写入希望抑制的警告信息

一般方便就是@SuppressWarnings({"all"})


注意:

SuppressWarnings作用范围和你放置的位置相关

比如:放在main方法头上,作用域就只有main方法,对其他类成员无效

2、元注解(了解):对注解进行注解


Retention注解


Target注解

Documented注解

Inherited注解

内部类、枚举、注解练习题

第一题

考点:static变量,对不同的对象是共享的
输出:
9.0 red
100 red


第二题

考点:匿名内部类,调用

第一种方法:匿名内部类作为对象,直接调用方法

public class Test {public static void main(String[] args) {CellPhone cellPhone = new CellPhone();cellPhone.testWork();}
}interface Computer {void work();
}
class CellPhone {public void testWork(){new Computer(){@Overridepublic void work() {System.out.println("手机在工作");}}.work();}
}

第二种方法:匿名内部类作为参数传递

public class Test {public static void main(String[] args) {CellPhone cellPhone = new CellPhone();cellPhone.testWork(new Computer() {@Overridepublic void work() {System.out.println("手机在工作");}});}
}interface Computer {void work();
}
class CellPhone {public void testWork(Computer computer){computer.work();}
}

第三题

考点:局部内部类,重名属性

public class Test {public static void main(String[] args) {A a = new A();a.m1();}
}class A {private final String NAME = "李三";public void m1(){class B {private final String NAME = "张三";public void show(){System.out.println(NAME);System.out.println(A.this.NAME);}}//下面这段代码不能放在class B{}前面,因为classB也是一个局部变量//局部变量还没有创建的时候,不能使用它B b = new B();b.show();}
}

第四题


版本一:通过设置isRiver来判断是否过河,输出只有一句

public class Test {public static void main(String[] args) {Boolean isRiver = false;Person person = new Person("唐僧", null);person.work(isRiver);}
}interface Vehicles {void work();
}
class Horse implements Vehicles {@Overridepublic void work() {System.out.println("骑马走...");}
}class Boat implements Vehicles {@Overridepublic void work() {System.out.println("坐船过...");}
}class Factory {//这里,将方法做成static比较方便(不用创建对象)public static Horse getHorse(){return new Horse();}public static Boat getBoat(){return new Boat();}
}class Person {private String name;private Vehicles vehicles;public Person(String name, Vehicles vehicles) {this.name = name;this.vehicles = vehicles;}//这里涉及到一个编程思路,就是可以把具体的要求,封装成方法 -> 这里就是编程思想//如何不浪费属性Vehiclepublic void work(Boolean isRiver){//向上转型if(isRiver){vehicles = Factory.getBoat();} else {vehicles = Factory.getHorse();}vehicles.work(); //动态绑定}public String getName(){return name;}
}

题目增加条件:唐僧过火焰山,用飞机
版本二:分别调用过河和一般情况,参数额外判断

public class Test {public static void main(String[] args) {Boolean isRiver = false;Person person = new Person("唐僧", null);person.Common();person.passRiver();person.passMountain();person.passRiver();person.Common();}
}interface Vehicles {void work();
}
class Horse implements Vehicles {@Overridepublic void work() {System.out.println("Common:一般情况,骑马走...");}
}class Boat implements Vehicles {@Overridepublic void work() {System.out.println("PassRiver:遇到河流,坐船过...");}
}
class Plane implements Vehicles {@Overridepublic void work() {System.out.println("PassMountain: 遇到火山,用飞机...");}
}class Factory {//存储马:static是公共共享空间//饿汉式private static Horse horse = new Horse();private Factory(){};//这里,将方法做成static比较方便(不用创建对象)public static Horse getHorse(){//返回的马应该是只有一匹马,第一次取到马之后就固定了return horse;}public static Boat getBoat(){return new Boat();}public static Plane getPlane() {return new Plane();}
}class Person {private String name;private Vehicles vehicles;public Person(String name, Vehicles vehicles) {this.name = name;this.vehicles = vehicles;}//这里涉及到一个编程思路,就是可以把具体的要求,封装成方法 -> 这里就是编程思想//如何不浪费属性Vehicle//传入的参数vehicles有三种情况:null、Boat、Horsepublic void passRiver() { //当传入null和Horse时,需要将vehicles改为Boatif(!(vehicles instanceof Boat)){vehicles = Factory.getBoat();}vehicles.work();}//过火焰山用飞机public void passMountain() {if(!(vehicles instanceof Plane)){vehicles = Factory.getPlane();}vehicles.work();}public void Common() {if(!(vehicles instanceof Horse)){vehicles = Factory.getHorse();}vehicles.work();}public String getName(){return name;}
}

第五题

考点:成员内部类的调用

public class Test {public static void main(String[] args) {Car car1 = new Car(40.6);Car car2 = new Car(41.6);Car car3 = new Car(25.6);Car car4 = new Car(-3.6);car1.m(); //或者car1.getAir().flow();car2.m();car3.m();car4.m();}
}class Car {private double temperature;public Car(double temperature) {this.temperature = temperature;}class Air {public void flow(){if(temperature > 40) {System.out.println("吹冷气");} else if(temperature < 0){System.out.println("吹暖气");} else {System.out.println("关空调");}}}public Air getAir(){return new Air();}public void m(){Air air = new Air();air.flow();}
}

第六题

考点:枚举、枚举再switch中的使用

switch(枚举对象){case 枚举名1:...break;case 枚举名2:...break;
}
public class Test {public static void main(String[] args) {Color[] colors = Color.values();for(Color color : colors){switch (color){case RED:System.out.println("匹配到红色");break;case BLUE:System.out.println("匹配到蓝色");break;case BLACK:System.out.println("匹配到黑色");break;case YELLOW:System.out.println("匹配到黄色");break;case GREEN:System.out.println("匹配到绿色");break;default:System.out.println("没有匹配到");break;}}}
}enum Color implements IA{RED(255,0,0),BLUE(0,0,255),BLACK(0,0,0),YELLOW(255,255,0),GREEN(0,255,0);private int redValue;private int greenValue;private int blueValue;Color(int redValue, int greenValue, int blueValue) {this.redValue = redValue;this.greenValue = greenValue;this.blueValue = blueValue;}@Overridepublic void show() {System.out.println("redValue=" + redValue + "  greenValue=" + greenValue + "  blueValue=" + blueValue);}
}interface IA {void show();
}

异常Exception

1、异常的概念

  • 异常的出现:

    程序中出现了一个不算致命的问题,就导致整个程序抛出异常后退出(崩溃),这不合理。
    所以在发现异常后,程序仍然能够继续执行,这就是java异常处理机制

  • 异常基本概念:

    java中,将程序执行过程发生的不正常情况称为“异常”(语法错误和逻辑错误和不是异常)

  • 异常分为两类

    • Error(错误):Java虚拟机无法解决的严重错误。如StackOverflowError栈溢出,OOM(out of memory)程序会崩溃。
    • Exception :其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码处理。例如空指针访问,网络连接中断等等。
      • Exception分为两大类:
      • 运行时异常【程序运行时发生的异常】
      • 编译时异常【编程时,编译器检查出的异常】

2、异常体系图⭐⭐⭐

类的异常体系图,体现了继承和实现关系

小结

3、常见的异常

① 常见的运行时异常

1)NullPointerException空指针异常
当应用程序试图在需要对象的地方使用null时,抛出该异常

public class Test {public static void main(String[] args) {String name = null;System.out.println(name.length());}
}

2)ArithmeticException数学运算异常
当出现异常的运算条件时,抛出此异常,比如除以0

3)ArrayIndexOutOfBoundsException数组下标越界异常
用非法所哟i你访问数组时抛出的异常,如果索引为负或者大于等于数组大小,则该索引为非法索引

4)ClassCastException类型转换异常
当试图将对象强制转换为不是实例运行类型或者其子类时,抛出该异常。(向下向上转型错误)

class A{}
class B extends A{}
class C extends A{}
A a = new B(); //向上转型
B b = (B)a; //向下转型
C c = (C)a; //转型错误,因为a的运行类型是B,和C无关

5)NumberFormatException数字格式不正确异常
当应用程序试图将字符串转换成一种数值类型,但该字符串不能抓换位适当格式时,抛出该异常 =》 使用异常我们可以确保输入的是 满足条件的 数字

String name = "你好";
int num = Integer.parseInt(name);

② 常见的编译异常

1)SQLException //操作数据库时,查询表可能发生异常

2)IOException //操作文件时,发生的异常

3)FILENotFoundException //当操作一个不存在的文件时,发生异常

4)ClassNotFoundException //加载类时,该类不存在,发生异常

5)EOFException //操作文件,到文件末尾,发生异常

6)IllegalArgumentException //参数异常

4、异常处理概念和处理机制图

  1. 基本介绍

异常处理就是当异常发生时,对异常处理的方式

  1. 异常处理的方式

    1)try-catch-finally
    程序员在代码中捕获发生的异常,自行处理


2)throws
将发生的异常抛出,交给调用者(方法)来处理,最顶级的处理者就是JVM
不用try-catch时,默认用throws(隐式的)

5、异常处理分类

1)try-catch

  1. 如果异常发生了,则异常发生后面的代码不会执行,直接进入到catch块

  2. 如果异常没有发生,则顺序执行try代码块,不会进入到catch

  3. 如果希望不管是否发生异常,都执行某段代码(比如关闭连接,释放资源等),则使用fianlly{}

public class TryCatchDetail {public static void main(String[] args) {try {String str = "你好";int a = Integer.parseInt(str);System.out.println("数字:" + a); //1. 一旦发生异常,这句代码不会执行,而是直接进入到catch块} catch (NumberFormatException e) {System.out.println("异常信息:" + e.getMessage());} finally {System.out.println("finally代码块被执行...");}System.out.println("程序继续...");}
}
  1. 可以有多个catch语句,捕获不同的异常(进行不同的业务处理),要求父类异常在后,子类异常在前,比如(Exception在后,NullPointerException在前),如果发生异常,只会匹配一个catch
public class TryCatchDetail {public static void main(String[] args) {try {Person person = new Person();person = null;System.out.println(person.getName()); //NullPointerExceptionint n1 = 10;int n2 = 0;int res = n1 / n2; //ArithmeticException//↓下面捕获三种异常,子类在前,父类在后(否则父类异常包含子类异常,子类异常永远用不到)} catch (NullPointerException e) {System.out.println("空指针异常=" + e.getMessage());} catch (ArithmeticException e) {System.out.println("算术异常=" + e.getMessage());} catch (Exception e) {System.out.println("父类异常=" + e.getMessage());} finally {}}
}class Person {private String name = "jack";public String getName() {return name;}
}
  1. 可以进行try-finally配合使用,这种用法相当于没有捕获异常,因此程序会直接崩掉/退出。【应用场景:执行一段代码,不管是否发生异常,都必须执行某个业务逻辑(检测到异常时并不马上崩掉,而是执行完这段finally代码后再崩)】
public class TryCatchDetail {public static void main(String[] args) {try {int n1 = 10;int n2 = 0;System.out.println(n1 / n2);} finally {System.out.println("执行了finally..");}System.out.println("程序继续执行..");}
}

输出:

2)throws



注意事项

3)如下图,NullPointerException是RuntimeException的子类

4)抛出的(编译)异常有两种处理方式:调用者也抛出异常,或者调用者内部使用try-catch处理异常

抛出运行异常可以不做处理

6、自定义异常

基本概念

自定义异常的步骤

public class CustomException {public static void main(String[] args) /* throws AgeException */{int age = 80;if(!(age >= 18 && age <= 120)){//这里通过构造器,设置信息throw new AgeException("年龄需要在18 ~ 120之间");//throw和throws的区别看后文}}
}//一般继承运行时异常
//如果是继承编译异常Exception,调用者需要throws AgeException
class AgeException extends RuntimeException {public AgeException(String message) { //构造器super(message);}
}

7、throw和throws的对比

8、异常练习

【第一题】

输出:
i=4
3


【第二题】
如果用户输入的不是一个整数,就提示他反复输入,直到输入一个整数为止

public class Test {public static void main(String[] args) {int n = 0;Scanner scanner = new Scanner(System.in);while(true){System.out.print("请输入一个整数:");try {n = Integer.parseInt(scanner.next()); //容易有NumberFormatExceptionSystem.out.println("你输入的整数为:" + n);break;} catch (NumberFormatException e) {System.out.println("你输入的不是一个整数,请重新输入!");}}}
}


【第三题】

下面的测试输出什么

当try中存在return或者throw时,finally优先于return和throw运行
当存在catch时,catch优先于finally运行

输出:


【第四题】

public class EcmDef {public static void main(String[] args) {try {//ArrayIndexOutOfBoundsExceptionif(args.length != 2) {throw new ArrayIndexOutOfBoundsException("缺少命令行参数或参数个数不对");}//NumberFormatExceptionint n1 = Integer.parseInt(args[0]);int n2 = Integer.parseInt(args[1]);//ArithmeticExceptiondouble res = cal(n1, n2);//三个异常都通过,则执行下面代码(输出结果)System.out.println("n1/n2 => " + n1 + "/" + n2 + "=" + cal(n1, n2));} catch(ArrayIndexOutOfBoundsException e) {System.out.println("缺少命令行参数");//注意,空指针异常是有数组元素,只不过没有初始化,而不是缺少元素(命令行参数)} catch(NumberFormatException e) {System.out.println("数据格式不正确");} catch(ArithmeticException e) {System.out.println("不能除0");}}public static double cal(int n1, int n2) {return n1 / n2;}
}

【第五题】



【第六题】
写出运行结果

JAVA笔记(十五):枚举类、注解、异常相关推荐

  1. python学习笔记(十五) -- 枚举

    枚举 枚举的作用就是定义一组 数据形式为 dict 但却又不可变的常量 比如我们定义一个类,或者定义一个dict ,类中的成员变量可以被更改,而且类又可以被实例化,dict 里面的值也可以被更改. 如 ...

  2. Effective Java笔记第五章枚举和注解第三节用EnumSet代替位域

    Effective Java笔记第五章枚举和注解 第三节用EnumSet代替位域 在以前如果一个枚举类型的元素主要用在集合中,一般就会使用int枚举模式.比如说: public class Demo ...

  3. Java基础学习——第十章 枚举类注解

    Java基础学习--第十章 枚举类&注解 一.枚举类(enum) 1. 枚举类的概念 枚举类:类的对象只有有限个,确定的 线程状态:创建.就绪.运行.阻塞.死亡 当需要定义一组常量时,强烈建议 ...

  4. Java笔记整理五(Iterator接口,泛型,常见数据结构(栈,队列,数组,链表,红黑树,集合),jdk新特性,异常,多线程,Lambda表达式)

    Java笔记整理五 1.1Iterator接口 Collection接口与Map接口主要用于存储元素,而Iterator主要用于迭代访问(即遍历)Collection中的元素,因此Iterator对象 ...

  5. 《Windows核心编程》读书笔记二十五章 未处理异常,向量化异常处理与C++异常

    第二十五章  未处理异常,向量化异常处理与C++异常 本章内容 25.1 UnhandledExceptionFilter函数详解 25.2 即时调试 25.3 电子表格示例程序 25.4 向量化异常 ...

  6. Polyworks脚本开发学习笔记(十五)-用Python连接Polyworks的COM组件

    Polyworks脚本开发学习笔记(十五)-用Python连接Polyworks的COM组件 用Polyworks脚本开发,没有高级语言的支持,功能难免单一,一些比较复杂的交互实现不了,界面和报告也很 ...

  7. Windows异常学习笔记(五)—— 未处理异常

    Windows异常学习笔记(五)-- 未处理异常 要点回顾 最后一道防线 实验一:理解最后一道防线 实验二:新线程的最后一道防线 总结 UnhandledExceptionFilter 实验三:理解U ...

  8. Java面试知识点:Date类、异常

    问题:Java面试知识点:Date类.异常 答案: 1.Date类 代码如下: (1)创建日期: package com.xy;import java.util.Date;/*** @ProjectN ...

  9. python复制指定字符串_python3.4学习笔记(十五) 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)...

    python3.4学习笔记(十五) 字符串操作(string替换.删除.截取.复制.连接.比较.查找.包含.大小写转换.分割等) python print 不换行(在后面加上,end=''),prin ...

  10. Java学习总结3——枚举类和反射机制

    Java枚举类和反射机制 一.Java枚举类(Enum): 在某些情况下,一个类的对象是有限且固定的,对于这种对象的实例有限且固定的类,在 Java 中被称为枚举类(Enum):枚举类是为了提高代码可 ...

最新文章

  1. 程序员的反击!每天一个离职小技巧
  2. SwiftSuspenders 1.6 浅出深入 深入 2
  3. jquery学习之重要知识点
  4. Spring AOP基础—JDK动态代理
  5. php框架之laravel
  6. 无尽包围html5游戏在线玩,小团体激发潜能小游戏突破自我
  7. C#算法设计查找篇之05-二叉树查找
  8. IOS端与Java端MD5加密方法
  9. 爬虫之Xpath的使用
  10. sap 双计量单位_[原创]浅谈MM模块的双计量单位(二)
  11. c 标签 foreach里面套choose做判断
  12. spotfire Document Property
  13. ubuntu中fcitx输入法不显示拼音与候选词框
  14. 一文盘点中国商业航天:民营火箭的两类瓶颈和三大趋势
  15. 标准功能模块组件 -- 内部联络单组件,内部邮件组件,提高多人异地协同办公效率
  16. 微信企业号开发七:JSAPI模式
  17. Enriched Feature Guided Refinement Network for Object Detection(面向目标检测的丰富特征引导细化网络)
  18. week6 day4 并发编程之多线程 理论
  19. 好久不见,我回来了!
  20. vue上下全屏翻页_全屏翻页布局

热门文章

  1. 华为服务器 修改管理地址吗,华为服务器 修改管理地址吗
  2. 1151. 【克罗地亚】pjesma
  3. 求字符串长度Strlen的三种方式
  4. System.Runtime.InteropServices.COMException:“对 COM 组件的调用返回了错误 HRESULT E_FAIL
  5. 如何配置IIS运行 ASPX
  6. JDBC插入数据时中文变为问号的解决方法
  7. Codeforces Round #663 (Div. 2) (CD)
  8. 文本超出长度用用省略号显示
  9. 非计算机专业特别是人文社科,中职非计算机专业《计算机应用基础》教学必须重视学情分析...
  10. 机器人中的数值优化(三)—— 无约束最优化方法基础、线搜索准则