枚举类型可以取代以往常量的定义方式,即将常量封装在类或接口中,此外,它还提供了安全检查功能。

泛型的出现不仅可以让程序员少写某些代码,主要的作用是解决类型安全问题,它提供编译时的安全检查, 不会因为将对象置于某个容器中而失去其类型。

11.1 枚举
        枚举是一种数据类型,它是一系列具有名称的常量的集合。比如在数学中所学的合:A=123},当使用这个集合时, 只能使用集合中的1、2、3 这3个元素,不是这3个元素的值就无法使用。

Java中的枚举是同样的道理,比如在程序中定义了一个性别枚举,里面只有两个值:男、女,那么在使用该枚举时,只能使用男和女这两个值,其他的任何值都是无法使用的。

1.使用枚举类型设置常量

以往设置常量,通常将常量放置在接口中,这这样在程序中就可以直接使用,并且该常量不能被修改,因为在接口中定义常量时,该常量的修饰行符为final与static。

例如,在项目中创建 Constants接口,在接口中定义常量的常规规方式。

public interface Constants {public static final int Constants_A=1;public static final int Constants_B=12;
}

在JDK 1.5版本中新增枚举类型后就逐渐取代了这种常量定义方式,因为通过使用枚举类型,可以赋予程序在编译时进行检查的功能。使用枚举类型定义常量的语法如下:

public enum Constants{Constants A, Constants B, Constants C;
}

其中,enum 是定义枚举类型的关键字。当需要在程序中使用用该常量时,可以使用 Constants. Constants_A 来表示。

例:

package eleven01;interface Constants { // 将常量放置在接口中public static final int Constants_A = 1;public static final int Constants_B = 12;
}public class ConstantsTest {enum Constants2 { // 将常量放置在枚举类型中Constants_A, Constants_B}// 使用接口定义常量public static void doit(int c) { // 定义一个方法,这里的参数为int型switch (c) { // 根据常量的值做不同操作case Constants.Constants_A:System.out.println("doit() Constants_A");break;case Constants.Constants_B:System.out.println("doit() Constants_B");break;}}public static void doit2(Constants2 c) { // 定义一个参数对象是枚举类型的方法switch (c) { // 根据枚举类型对象做不同操作case Constants_A:System.out.println("doit2() Constants_A");break;case Constants_B:System.out.println("doit2() Constants_B");break;}}public static void main(String[] args) {ConstantsTest.doit(Constants.Constants_A); // 使用接口中定义的常量ConstantsTest.doit2(Constants2.Constants_A); // 使用枚举类型中的常量ConstantsTest.doit2(Constants2.Constants_B); // 使用枚举类型中的常量ConstantsTest.doit(3);// ConstantsTest.doit2(3);}
}

运行结果如下:

注:

枚举类型可以在类的内部进行定义,也可以在类的外音部定义。如果在类的内部定义,则类似于内部类形式,比如例 11.1 中,当编译该类时,除了ConstantsTest.c lass 外,还存在 ConstantsTest$1.class 与 ConstantsTest$Constants2.class文件。

2.深入了解枚举类型

操作枚举类型成员的方法

枚举类型较传统定义常量的方式,除了具有参数类型检测的优势之外,还具有其他方面的优势。

用户可以将一个枚举类型看作是一个类,它继承于java.langEnum类,当定义一个枚举类型时,每一个枚举类型成员都可以看作是枚举类型的一个 实例,这些枚举类型成员都默认被final、public、static 修饰,所以当使用枚举类型成员时直接使用枚举类型名称调用枚举类型成员即可。

由于枚举类型对象继承于java.langEnum 类, 所以该类中一些操作枚举类型的方法都可以应用到枚举类型中。

枚举类类型的常用方法

方法名称    具体含义    使用方法
values()    该方法可以将枚举类型成员以数组的形式返回    枚举类型名称.values()
valueOf()    该方法可以实现将普通字符串转换为枚举实例    枚举类型名称valueOf("abc")
compareTo()    该方法用于比较两个枚举对象在定义时的顺序    枚举对象.compareTo()
ordinal()    该方法用于得到枚举成员的位置索引    枚举对象.ordinal()

1)values()

枚举类型实例包含一个values()方法,该方法可以将枚举类型成员以数组的形式返回。

例:

package eleven02;import static java.lang.System.out;public class ShowEnum {enum Constants2 { // 将常量放置在枚举类型中Constants_A, Constants_B}// 循环由values()方法返回的数组public static void main(String[] args) {for (int i = 0; i < Constants2.values().length; i++) {// 将枚举成员变量打印out.println("枚举类型成员变量:" + Constants2.values()[i]);}}
}

运行结果如下:

2)valueOf() 与 compareTo()

枚举类型中静态方法valueOf()可以将普通字符串转换为枚举类型,而compareTo()方法用于比较两个枚举类型成员定义时的顺序。调用 comparo eTo()方法时,如果方法中参数在调用该方法的枚举对象位置之前,则返回正整数;如果两个互相比较的枚举成员的位置相同,则返回 0;如果方法中参数在调用该方法的枚举对象位置之后,则返回负整数。

例:

package eleven03;import static java.lang.System.out;public class EnumMethodTest {enum Constants2 { // 将常量放置在枚举类型中Constants_A, Constants_B, Constants_C, Constants_D}// 定义比较枚举类型方法,参数类型为枚举类型public static void compare(Constants2 c) {// 根据values()方法返回的数组做循环操作for (int i = 0; i < Constants2.values().length; i++) {// 将比较结果返回out.println(c + "与" + Constants2.values()[i] + "的比较结果为:" + c.compareTo(Constants2.values()[i]));}}// 在主方法中调用compare()方法public static void main(String[] args) {compare(Constants2.valueOf("Constants_B"));}
}

运行结果如下:

枚举类型中的ordinal()方法用于获取某个枚举对象的位置索引值。

例:

package eleven04;public class EnumIndexTest {enum Constants2 { // 将常量放置在枚举类型中Constants_A, Constants_B, Constants_C}public static void main(String[] args) {for (int i = 0; i < Constants2.values().length; i++) {// 在循环中获取枚举类型成员的索引位置System.out.println(Constants2.values()[i] + "在枚举类型中位置索引值" + Constants2.values()[i].ordinal());}}
}

运行结果如下:

枚举类型中的构造方法

在枚举类型中,可以添加构造方法,但是规定这个构造方法必须为 private 修饰符或者默认修饰符所修饰。枚举类型定义的构造方法语法如下:

public enum Constants2{Constants_A("我是枚举成员A"),Constants_B("我是枚举成员B"),Constants_C("我是枚举成员C"),Constants_D(3);String description;int i;private Constants2(){ //定义默认构造方法 }//定义带参数的构造方法,参数类型为字符串型private Constants2(String description){this.description=description;private Constants2(int i){//定义带参数的构造方法,参数类型为整型this.i=this.i+i;}
}

从枚举类型构造方法的语法中可以看出,无论是无参构造方法还是有参构造方法,修饰权限都为private。

定义一个有参构造方法后,需要对枚举类型成员相应地使用该构造方法,如Constants_A(我是枚举成员A")和 Constants_D(3)语句,相应地使用了参数为 String 型和参数为 int 型的构造方法。然后可以在枚举类型中定义两个成员变量,在构造方法中为这两个成员变量赋值,这样就可以在枚举类型中定义该成员变量的getXXX()方法了。

例:

package eleven05;import static java.lang.System.out;public class EnumConTest {enum Constants2 { // 将常量放置在枚举类型中Constants_A("我是枚举成员A"), // 定义带参数的枚举类型成员Constants_B("我是枚举成员B"), Constants_C("我是枚举成员C"), Constants_D(3);private String description;private int i = 4;private Constants2() {}// 定义参数为String型的构造方法private Constants2(String description) {this.description = description;}// 定义参数为int型的构造方法private Constants2(int i) { this.i = this.i + i;}// 获取description的值public String getDescription() { return description;}// 获取i的值public int getI() { return i;}}public static void main(String[] args) {for (int i = 0; i < Constants2.values().length; i++) {out.println(Constants2.values()[i] + "调用getDescription()方法为:" + Constants2.values()[i].getDescription());}out.println(Constants2.valueOf("Constants_D") + "调用getI()方法为:" + Constants2.valueOf("Constants_D").getI());}
}

运行结果如下:

还可以将这个 getDescription()方法放置在接口中,使枚举类型实现该接口,然后使每个枚举类型实现接口中的方法。

package eleven06;public interface EnumInterface {public String getDescription();public int getI();
}
package eleven06;import static java.lang.System.out;public enum AnyEnum implements EnumInterface {Constants_A { // 可以在枚举类型成员内部设置方法public String getDescription() {return ("我是枚举成员A");}public int getI() {return i;}},Constants_B {public String getDescription() {return ("我是枚举成员B");}public int getI() {return i;}},Constants_C {public String getDescription() {return ("我是枚举成员C");}public int getI() {return i;}},Constants_D {public String getDescription() {return ("我是枚举成员D");}public int getI() {return i;}};private static int i = 5;public static void main(String[] args) {for (int i = 0; i < AnyEnum.values().length; i++) {out.println(AnyEnum.values()[i] + "调用getDescription()方法为:" + AnyEnum.values()[i].getDescription());out.println(AnyEnum.values()[i] + "调用getI()方法为:" + AnyEnum.values()[i].getI());}}
}

运行结果如下:

注:

1)从上面代码中可以看出,枚举类型可以实现一个或者多个接口,但是它不能继承类。因为编译器会默认将枚举类型继承自java.lang.Enum 类,这一过程由编译器完成。
        2)枚举类型中的常量成员必须在其他成员之前定义,否则这个枚举类型不会产生对象。

3.使用枚举类型的优势

枚举类型声明提供了一种用户友好的变量定义方法,枚举了某种数据类型所有可能出现的值。总结枚举类型,它具有以下特点:

(1)类型安全。
(2)紧凑有效的数据定义。
(3)可以和程序其他部分完美交互。

(4)运行效率高

11.2 泛型
1.回顾“向上转型”与“向下转型”
例:

package eleven07;public class Test {private Object b; // 定义Object类型成员变量public Object getB() { // 设置相应的getXXX()方法return b;}public void setB(Object b) { // 设置相应的setXXX()方法this.b = b;}public static void main(String[] args) {Test t = new Test();t.setB(new Boolean(true)); // 向上转型操作System.out.println(t.getB());t.setB(new Float(12.3));Float f = (Float) (t.getB()); // 向下转型操作System.out.println(f);}
}

运行结果如下:

2.定义泛型类
        Object类为最上层的父类,很多程序员为了使程序更为通用,设计程序时通常使传入的值与返回的值都以Object类型为主。当需要使用这些实例时,必须正确地将该实例转换为原来的类型,否则在运行时将会发生ClassCastException异常。
        在JDK1.5 版本以后,提出了泛型机制。其语法如下:

类名<T>

其中,T代表一个类型的名称。

将上一个代码改为定义类时使用泛型的形式。

package eleven07;public class OverClass<T> { // 定义泛型类private T over; // 定义泛型成员变量public T getOver() { // 设置相应的getXXX()方法return over;}public void setOver(T over) { // 设置相应的setXXX()方法this.over = over;}public static void main(String[] args) {//实例化一个Boolean型的对象OverClass<Boolean> over1 = new OverClass<Boolean>();//实例化一个Float型的对象OverClass<Float> over2 = new OverClass<Float>();over1.setOver(true);over2.setOver(12.3f);Boolean b = over1.getOver();Float f = over2.getOver(); System.out.println(b);System.out.println(f);}
}

运行结果如下:

使用泛型这种形式将不会发生ClassCastExce ption 异常,因为在编译器中就可以检查类型匹配是否正确。

例如,在项目中定义泛型类。

OverClass<Float> over2=new OverClass<F loat>(); 
over2.setover(12.3f);
//Integer i=over2.getOver();//不能将F1 oat型的值赋予Integer变量

注:

在定义泛型类时,一般类型名称使用T来表达,而容器的元素使用E来表达,具体的设置读者可以参看JDK 5.0以上版本的API。

3.泛型的常规用法
定义泛型类时声明多个类型
        在定义泛型类时,可以声明多个类型。语法如下:

MutiOverClass<T1,T2>
MutiOverClass:泛型类名称

其中,T1 和 T2 为可能被定义的类型。这样在实例化指定类型的对象时就可以指定多个类型。

MutiOverClass<Boolean,Float>=new Mutid OverClass<Boolean,Float>();

定义泛型类时声明数组类型
        定义泛型类时也可以声明数组类型,下面的实例中定义泛型时便声明了数组类型。

例:

package eleven08;public class ArrayClass<T> {private T[] array; // 定义泛型数组public void SetT(T[] array) { // 设置SetXXX()方法为成员数组赋值this.array = array;}public T[] getT() { // 获取成员数组return array;}public static void main(String[] args) {ArrayClass<String> a = new ArrayClass<String>();String[] array = { "成员1", "成员2", "成员3", "成员4", "成员5" };a.SetT(array); // 调用SetT()方法for (int i = 0; i < a.getT().length; i++) {System.out.println(a.getT()[i]); // 调用getT()方法返回数组中的值}}
}

运行结果如下:

此可见,可以在使用泛型机制时声明一个数组,但是不可以使用泛型来建立数组的实例。例如,下面的代码就是错误的:

public class ArrayClass <T>{//private T[] array=newT[10]; //不能使用泛型来建立数组的实例...
}

注:

JDK1.7版本中添加了一个新特性:自动推断实例化类型的泛型。所以这样的语法:         ArrayClass<String> a = new ArrayClass<>();

// 实现类的泛型为空会自动转换为:
        ArrayClass<String> a = new ArrayClass<String>();

集合类声明容器的元素
        实际应用中,通过在集合类中应用泛型可以使集合类中的元素类型保证唯一性,这样在运行时就不会产生ClassCastException异常,提高了代码的安全性和可维护性。可以使用K和V两个字符代表容器中的键值和与键值相对应的具体值。

例:

package eleven09;import java.util.*;public class MutiOverClass<K, V> {public Map<K, V> m = new HashMap<K, V>(); // 定义一个集合HashMap实例// 设置put()方法,将对应的键值与键名存入集合对象中public void put(K k, V v) {m.put(k, v);}public V get(K k) { // 根据键名获取键值return m.get(k);}public static void main(String[] args) {// 实例化泛型类对象MutiOverClass<Integer, String> mu = new MutiOverClass<Integer, String>();for (int i = 0; i < 5; i++) {// 根据集合的长度循环将键名与具体值放入集合中mu.put(i, "我是集合成员" + i);}for (int i = 0; i < mu.m.size(); i++) {// 调用get()方法获取集合中的值System.out.println(mu.get(i));}}
}

运行结果如下:

上面例子中泛型类 MutiOverClass 纯属多余,因为在 Java 中集合架已经被泛型化了,可以在主方法中直接使用public Map<K,V> m=new HashMap<K,V>0;语句创建实例,然后相应调用Map接口中的 put()与get()方法完成填充容器或根据键名获取集合中具体值的功能。

集合中除了HashMap 这种集合类型之外,还包括 ArrayList、Vector等。表11.2列举了几个常用的被泛型化的集合类。

常用的被泛型化的集合类

集合类    泛型定义
ArrayList    ArrayList<E>
HashMap    HashMap<K,V>
HashSet    HashSet<E>
Vector    
Vector<E>

例:

package eleven10;import java.util.*;public class ListClass {public static void main(String[] args) {// 定义ArrayList容器,设置容器内的值类型为IntegerList<Integer> a = new ArrayList<Integer>();a.add(1); // 为容器添加新值for (int i = 0; i < a.size(); i++) {// 根据容器的长度循环显示容器内的值System.out.println("获取ArrayList容器的值:" + a.get(i));}// 定义Map容器,设置容器的键名与键值类型分别为Integer与String型Map<Integer, String> m = new HashMap<Integer, String>();for (int i = 0; i < 5; i++) {m.put(i, "成员" + i); // 为容器填充键名与键值}for (int i = 0; i < m.size(); i++) {// 根据键名获取键值System.out.println("获取Map容器的值" + m.get(i));}// 定义set容器,使容器中的内容为Character型Set<Character> set = new HashSet<Character>();//为容器添加新值set.add('一');set.add('二');//使用foreach循环,将set中元素按照Character类型进行循环遍历for (Character c: set) {// 显示容器中的内容System.out.println("获取set容器的值:" + c);}}
}

运行结果如下:

注:

在定义集合对象时,如果没有指定具体的类型,泛型参数<T>的类型默认为<Object>,这时运行程序不会报错但是会有警告信息。

4.泛型的高级用法

泛型的高级用法主要包括通过类型参数T的继承和通过类型通配符的继承来限制泛型类型,另
外,开发人员还可以继承泛型类或者实现泛型接 口,本节将对泛型的一些高级用法进行讲解。

通过类型参数T的继承限制泛型类型
        默认可以使用任何类型来实例化一个泛型类对象,但Java中也对泛型类实例的类型作了限制,这主要通过对类型参数T实现继承来体现,语法如下:

class 类名称<T extends anyClass>

例:

package eleven;import java.util.*;public class LimitClass<T extends List> { // 限制泛型的类型public static void main(String[] args) {// 可以实例化已经实现List接口的类LimitClass<ArrayList> l1 = new LimitClass<ArrayList>();LimitClass<LinkedList> l2 = new LimitClass<LinkedList>();// 这句是错误的,因为HashMap没有实现List()接口LimitClass<HashMap> l3 = new LimitClass<HashMap>();}}

通过类型通配符的继承限制泛型类型   
        在泛型机制中,提供了类型通配符,其主要作用是在创建一个泛型类对象时,限制这个泛型类的类型,或者限制这个泛型类型必须继承某个接口或某个类(或其子类)。要声明这样一个对象可以使用“?”通配符,同时使用 extends 关键字来对泛型加以限制。

注:

通过对类型参数T 过对类型通配符实现继承限制泛型类型时,则在实例化时才进行限制。

使用泛型类型通配符的语法如下:

泛型类名称<? extends list> a=null;

其中,<? extends List>表示类型未知,当需要使用该泛型对象时,可以单独实例化。

例如,在项目中创建一个类文件,在该类中限制泛型类型。

A<? extends list> a=null;:
a=new A<ArrayList>();
a=new A<LinkedList>();
package eleven11;import java.util.*;public class WildClass {public static void main(String[] args) {List<String> l1 = new ArrayList<String>(); // 创建一个ArrayList对象l1.add("成员"); // 在集合中添加内容List<?> l2 = l1; // 使用通配符List<?> l3 = new LinkedList<Integer>();System.out.println("l1:" + l1.get(0)); // 获取l1集合中第一个值System.out.println("l2:" + l2.get(0)); // 获取l2集合中第一个值l1.set(0, "成员改变"); // 没有使用通配符的对象调用set()方法// l2.add("添加");// 使用通配符的对象不能调用add方法// l2.set(0, "成员改变"); // 使用通配符的对象不能调用set()方法// l3.add(1);// l3.set(0, 1);System.out.println("l1:" + l1.get(0)); // 可以使用l1的实例获取集合中的值}
}

运行结果如下:

技巧:

泛型类型限制除了可以向下限制之外,还可以向上限制,只要在定义时使用super 关键字即可。例如,A<? super List>a=null;”这样定义后,对象a只接受List接口或上层父类类型,如 a=new A<Object>O;。

继承泛型类与实现泛型接口
        定义为泛型的类和接口也可以被继承与实现。

在项目中创建一个类文件,在该类中继承泛型类。

public class Extendclass<ti> {
}Class SubClass<Tl,T2,T3> extends ExtendClass<T1>{// 泛型可以比父类多,但不可以比父类少
}

如果在 SubClass 类继承 ExtendClass类时保留父类的泛型类型,需要在继承时指明,如果没有指明,直接使用 extends ExtendsClass 语句进行继承操作,则 SubClass类中的T1、T2和T3都会自动变为Object,所以在一般情况下都将父类的泛型类型保留。

定义的泛型接口也可以被实现。

在项目中创建一个类文件,在该类中实现泛型接口。

interface TestInterface<Tl> {
}class SubClass2<T1, T2, T3> implements TestInterface<Ti> {
}

5.泛型总结
        使用泛型需遵循以下原则。

(1)泛型的类型参数只能是类类型,不可以是简单类型,如A<int>这种泛型定义就是错误的。

(2)泛型的类型个数可以是多个。
(3)可以使用extends关键字限制泛型的类类型。

(4)可以使用通配符限制泛型的类型。

第十一章 枚举与泛型相关推荐

  1. ios 获取一个枚举的所有值_凯哥带你从零学大数据系列之Java篇---第十一章:枚举...

    温馨提示:如果想学扎实,一定要从头开始看凯哥的一系列文章(凯哥带你从零学大数据系列),千万不要从中间的某个部分开始看,知识前后是有很大关联,否则学习效果会打折扣. 系列文章第一篇是拥抱大数据:凯哥带你 ...

  2. Kotlin学习笔记 第二章 类与对象 第十一节 枚举类 第八节密封类

    参考链接 Kotlin官方文档 https://kotlinlang.org/docs/home.html 中文网站 https://www.kotlincn.net/docs/reference/p ...

  3. 第11-15章枚举|异常|常用类|集合|泛型

    文章目录 第11章 枚举和注解 11.1举例 11.2枚举的二种实现方式 11.3enum 实现接口 11.4注解的理解 11.4基本的 Annotation 介绍 第12章 异常-Exception ...

  4. 20190922 On Java8 第二十一章 数组

    第二十一章 数组 一等对象 对象数组和基元数组在使用上是完全相同的.唯一的不同之处就是对象数组存储的是对象的引用,而基元数组则直接存储基本数据类型的值. 多维数组 Array.deepToString ...

  5. 读书笔记:《C++ PrimerPlus》 第九章~第十一章

    第一章 预备知识 第二章 开始学习C++ 第三章 处理数据 第四章 复合类型 第五章 循环和关系表达式 第六章 分支语句和逻辑运算符 第七章 函数--C++的编程模块 第八章 函数探幽 第九章 内存模 ...

  6. 【正点原子STM32连载】第二十一章 通用定时器实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1

    1)实验平台:正点原子MiniPro H750开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=677017430560 3)全套实验源码+手册+视频 ...

  7. 第十一章 Direct3D Initialization

    第十一章 Direct3D Initialization 本章将完成渲染引擎的基础部分的最后一个模块Direct3D的初始化,学习Direct3D C++ API,并完成一个Direct3D应用程序. ...

  8. 【正点原子STM32连载】 第三十一章 ADC实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1

    1)实验平台:正点原子MiniPro H750开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=677017430560 3)全套实验源码+手册+视频 ...

  9. 第十一章.软件工程(下)

    目录 第十一章.软件工程 第九节.面向对象设计 面向对象(OAA)的基本概念 面向对象开发各阶段划分及任务 OOA 设计原则 OOA - UML OOA 设计模式的概念 OOA 设计模式的分类 创建型 ...

  10. [swift 进阶]读书笔记-第十一章:互用性 C11P1 实践:封装 CommonMark

    第十一章:互用性 Interoperability 前言: swift 的最大优点就是与C 或者 OC 混编的时候稳的一匹 本章主要讲了swift和C之间的一些知识点. 11.1 实践:封装 Comm ...

最新文章

  1. 如何发布Node模块到NPM社区
  2. 基于eclipse创建android的helloworld工程
  3. 流量暴涨擒凶记(转)
  4. 【星球知识卡片】深度学习换脸算法都有哪些?如何长期进行学习
  5. VMware Workstation 8 技巧集
  6. 面向对象实现ATM功能
  7. LabelSmooth
  8. 趣达学院学习有奖活动!
  9. 内网穿透工具,微信支付支付宝支付的沙箱接口回调地址
  10. 168. Excel表列名称
  11. 关键词排名的查询方法
  12. F5 微信银行解决方案
  13. 中国通史—春秋战国的学术思想
  14. C++多线程启动、暂停、继续与停止
  15. source 命令解释
  16. VS code之代码格式化快捷键
  17. 2021年安全员-B证考试及安全员-B证考试试题
  18. 人人都想买湖景房!湖景房优缺点你知道吗?
  19. 乐鑫M5GO自制睡眠小助手!新手。。。轻打脸
  20. 计算机硬件相关文献,计算机硬件维护外文外文 计算机硬件维护专著类参考文献哪里找...

热门文章

  1. 浏览器htmlcss面试题
  2. tensorflow目标检测--识别赵丽颖
  3. 基于jsp+mysql+Spring+mybatis java的SSM健身房管理系统
  4. adbdriver的安装
  5. luci网页shell_修改Luci界面
  6. B. Alice and the List of Presents(组合数学)
  7. 反编译工具的安装与使用(解决部分能反编译部分不能反编译)
  8. Python Flask 学习笔记 —— 二(路由,视图函数,jinjia2语法)
  9. “All in 2B”,信用算力是认真的?
  10. Android强大的控件——RecyclerView