1、晓之以理,动之以码

学Java就是很上头哦,一来直接三连问!!!

什么是泛型?为什么要用泛型?泛型怎么用?

当然泛型在Java中有很重要的一个地位,在面向对象编程以及在各种设计模式中有非常广泛的应用~

1.1 什么是泛型?

  1. 泛型:
    本意就是“参数化类型”。就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。

1.2  一个栗子

一个被举烂的例子

  1. package com.example.main;
  2.  
  3. /**
    * @author lin
    * @version 1.0
    * @date 2020/7/12 21:31
    * @Description TODO
    */
    public class TestTypeMain {
       private static int add(int a, int b) {
           System.out.println(+ "+" + b + "=" + (+ b));
           return a + b;
      }
  4.  
  5.    private static float add(float a, float b) {
           System.out.println(+ "+" + b + "=" + (+ b));
           return a + b;
      }
  6.  
  7.    private static double add(double a, double b) {
           System.out.println(+ "+" + b + "=" + (+ b));
           return a + b;
      }
  8.  
  9.    private static <extends Number> double add(T a, T b) {
           System.out.println(+ "+" + b + "=" + (a.doubleValue() + b.doubleValue()));
           return a.doubleValue() + b.doubleValue();
      }
  10.  
  11.    public static void main(String[] args) {
           System.out.println(TestTypeMain.add(1, 2));
           System.out.println(TestTypeMain.add(1f, 2f));
           System.out.println(TestTypeMain.add(1d, 2d));
           System.out.println(TestTypeMain.add(Integer.valueOf(1), Integer.valueOf(2)));
           System.out.println(TestTypeMain.add(Float.valueOf(1), Float.valueOf(2)));
           System.out.println(TestTypeMain.add(Double.valueOf(1), Double.valueOf(2)));
      }
  12.  
  13. }
    运行结果:
       1+2=3
       3
       1.0+2.0=3.0
       3.0
       1.0+2.0=3.0
       3.0
       1+2=3.0
       3.0
       1.0+2.0=3.0
       3.0
       1.0+2.0=3.0
       3.0

1.3 总结(意义):

1:减少代码,增强可读性,代码复用性更高

2:显性指定类型,编译器会自动检查,避免运行中的一半的错误。

2、泛型如何使用?

2.1 泛型可以用到哪里?

1、泛型方法:public static < E > void printArray( E[] inputArray )

public static <T extends Comparable<T>> T maximum(T x, T y, T z)

2、泛型类:public class Box<T> {  private T t; }

3、泛型接口:public interface Generator<T> { public T next(); }

4、泛型通配符:List<String> list= new ArrayList<String>();

2.2 泛型类型的变量

  1. E:元素(Element),多用于java集合框架
    K:关键字(Key
    N:数字(Number
    T:类型(Type
    V:值(Value

2.3 泛型方法

简单的泛型方法入门可以参考上面的那个栗子. 另外通过一个例子,把泛型方法再总结一下。

  1.    /**
        * 这才是一个真正的泛型方法。
        * 首先在public与返回值之间的<T>必不可少,这表明这是一个泛型方法,并且声明了一个泛型T
        * 这个T可以出现在这个泛型方法的任意位置.
        * 泛型的数量也可以为任意多个
        *   如:public <T,K> K showKeyName(Generic<T> container){
        *       ...
        *       }
        */
       public <T> T showKeyName(Generic<T> container){
           System.out.println("container key :" + container.getKey());
           //当然这个例子举的不太合适,只是为了说明泛型方法的特性。
           T test = container.getKey();
           return test;
      }
  2.  
  3.    //这也不是一个泛型方法,这就是一个普通的方法,只是使用了Generic<Number>这个泛型类做形参而已。
       public void showKeyValue1(Generic<Number> obj){
           Log.d("泛型测试","key value is " + obj.getKey());
      }
  4.  
  5.    //这也不是一个泛型方法,这也是一个普通的方法,只不过使用了泛型通配符?
       //同时这也印证了泛型通配符章节所描述的,?是一种类型实参,可以看做为Number等所有类的父类
       public void showKeyValue2(Generic<?> obj){
           Log.d("泛型测试","key value is " + obj.getKey());
      }
  6.  
  7.     /**
        * 这个方法是有问题的,编译器会为我们提示错误信息:"UnKnown class 'E' "
        * 虽然我们声明了<T>,也表明了这是一个可以处理泛型的类型的泛型方法。
        * 但是只声明了泛型类型T,并未声明泛型类型E,因此编译器并不知道该如何处理E这个类型。
       public <T> T showKeyName(Generic<E> container){
           ...
       }  
       */
  8.  
  9.    /**
        * 这个方法也是有问题的,编译器会为我们提示错误信息:"UnKnown class 'T' "
        * 对于编译器来说T这个类型并未项目中声明过,因此编译也不知道该如何编译这个类。
        * 所以这也不是一个正确的泛型方法声明。
       public void showkey(T genericObj){
  10.  
  11.    }
       */

此外:

  1.    /**
        * 这才是一个真正的泛型方法。
        * 首先在public与返回值之间的<T>必不可少,这表明这是一个泛型方法,并且声明了一个泛型T
        * 这个T可以出现在这个泛型方法的任意位置.
        * 泛型的数量也可以为任意多个
        *   如:public <T,K> K showKeyName(Generic<T> container){
        *       ...
        *       }
        */
       public <T> T showKeyName(Generic<T> container){
           System.out.println("container key :" + container.getKey());
           //当然这个例子举的不太合适,只是为了说明泛型方法的特性。
           T test = container.getKey();
           return test;
      }
  2.  
  3.    //这也不是一个泛型方法,这就是一个普通的方法,只是使用了Generic<Number>这个泛型类做形参而已。
       public void showKeyValue1(Generic<Number> obj){
           Log.d("泛型测试","key value is " + obj.getKey());
      }
  4.  
  5.    //这也不是一个泛型方法,这也是一个普通的方法,只不过使用了泛型通配符?
       //同时这也印证了泛型通配符章节所描述的,?是一种类型实参,可以看做为Number等所有类的父类
       public void showKeyValue2(Generic<?> obj){
           Log.d("泛型测试","key value is " + obj.getKey());
      }
  6.  
  7.     /**
        * 这个方法是有问题的,编译器会为我们提示错误信息:"UnKnown class 'E' "
        * 虽然我们声明了<T>,也表明了这是一个可以处理泛型的类型的泛型方法。
        * 但是只声明了泛型类型T,并未声明泛型类型E,因此编译器并不知道该如何处理E这个类型。
       public <T> T showKeyName(Generic<E> container){
           ...
       }  
       */
  8.  
  9.    /**
        * 这个方法也是有问题的,编译器会为我们提示错误信息:"UnKnown class 'T' "
        * 对于编译器来说T这个类型并未项目中声明过,因此编译也不知道该如何编译这个类。
        * 所以这也不是一个正确的泛型方法声明。
       public void showkey(T genericObj){
  10.  
  11.    }
       */

2.4 泛型类

定义一个泛型类:public class GenericClass{}

  1. package com.example.main;
  2.  
  3. /**
    * @author lin
    * @version 1.0
    * @date 2020/7/12 21:49
    * @Description 泛型类
    */
    public class GenericClass<T> {
       private T data;
  4.  
  5.    public T getData() {
           return data;
      }
  6.  
  7.    public void setData(T data) {
           this.data = data;
      }
  8.  
  9.    public static void main(String[] args) {
           GenericClass<String> genericClass = new GenericClass<>();
           genericClass.setData("Generic Class");
           System.out.println(genericClass.getData());
      }
    }

2.5 泛型接口

定义一个泛型接口:public interface GenericIntercace{}

  1. package com.example.main;
  2.  
  3. /**
    * @author lin
    * @version 1.0
    * @date 2020/7/12 21:50
    * @Description TODO
    */
    public interface GenericInterface<T> {
      public T getData();
    }

实现泛型接口不指定类型方式一:

public class ImplGenericInterface1 implements GenericIntercace

  1. package com.example.main;
  2.  
  3. /**
    * @author lin
    * @version 1.0
    * @date 2020/7/12 21:53
    * @Description TODO
    */
    public class ImplGenericInterface1<T> implements GenericInterface<T> {
       private T data;
  4.  
  5.    private void setData(T data) {
           this.data = data;
      }
  6.  
  7.    @Override
       public T getData() {
           return this.data;
      }
  8.  
  9.    public static void main(String[] args) {
           ImplGenericInterface1<String> implGenericInterface1 = new ImplGenericInterface1<>();
           implGenericInterface1.setData("Generic Interface1");
           System.out.println(implGenericInterface1.getData());
      }
    }

实现泛型接口指定类型方式二:

public class ImplGenericInterface2 implements GenericIntercace<String> {}

  1. package com.example.main;
  2.  
  3. /**
    * @author lin
    * @version 1.0
    * @date 2020/7/12 21:55
    * @Description TODO
    */
    public class ImplGenericInterface2 implements GenericInterface<String> {
       @Override
       public String getData() {
           return "hello world ";
      }
  4.  
  5.    public static void main(String[] args) {
           ImplGenericInterface2 implGenericInterface2 = new ImplGenericInterface2();
           System.out.println(implGenericInterface2.getData());
      }
    }

2.6 泛型通配符

引入通配符可以在泛型实例化时更加灵活地控制,也可以在方法中控制方法的参数。

语法如下:

泛型类名<? extends T> 或 泛型类名<? super T> 或 泛型类名<?>? extends T:表示T或T的子类

? super T:表示T或T的父类

?:表示可以是任意类型

常用的 T,E,K,V,?

本质上这些个都是通配符,没啥区别,只不过是编码时的一种约定俗成的东西。比如上述代码中的 T ,我们可以换成 A-Z 之间的任何一个 字母都可以,并不会影响程序的正常运行,但是如果换成其他的字母代替 T ,在可读性上可能会弱一些。通常情况下,T,E,K,V,?是这样约定的:

2.6.1、?表示不确定的 java 类型

  1. static int countLegs (List<? extends Animal > animals ) {
       int retVal = 0;
       for ( Animal animal : animals )
      {
           retVal += animal.countLegs();
      }
       return retVal;
    }
  2.  
  3. static int countLegs1 (List< Animal > animals ){
       int retVal = 0;
       for ( Animal animal : animals )
      {
           retVal += animal.countLegs();
      }
       return retVal;
    }

2.6.2、T (type) 表示具体的一个java类型

下界: 用 super 进行声明,表示参数化的类型可能是所指定的类型,或者是此类型的父类型,直至 Object

  1. 在类型参数中使用 super 表示这个泛型中的参数必须是 E 或者 E 的父类。
  2.  
  3. private <T> void test(List<? super T> dst, List<T> src){
       for (T t : src) {
           dst.add(t);
      }
    }
  4.  
  5. public static void main(String[] args) {
       List<Dog> dogs = new ArrayList<>();
       List<Animal> animals = new ArrayList<>();
       new Test3().test(animals,dogs);
    }

实例:

  1. class gent<T> {
       public void test() {
           System.out.println("gent");
      }
    }
  2.  
  3. class supC {
       public String toString() {
           return "supA";
      }
    }
  4.  
  5. public class Bc extends supC {
       String b;
  6.  
  7.    public Bc( String b ) {
           this.= b;
      }
  8.  
  9.    public String toString() {
           return "subB";
      }
  10.  
  11.    // 指明泛型参数必须是supC或其子类
       public void test( gent<? extends supC> o ) {
           System.out.println("Bc");
      }
  12.  
  13.    public static void main( String[] args ) {
           Bc bc = new Bc("test");
           gent<Bc> oGent = new gent<Bc>();
           bc.test(oGent);    // oGent 是supC的子类对象
      }
    }

3、泛型注意点

3.1 静态方法与泛型

静态方法有一种情况需要注意一下,那就是在类中的静态方法使用泛型:静态方法无法访问类上定义的泛型;如果静态方法操作的引用数据类型不确定的时候,必须要将泛型定义在方法上。

即:如果静态方法要使用泛型的话,必须将静态方法也定义成泛型方法 。

  1. public class StaticGenerator<T> {
      ....
      ....
       /**
        * 如果在类中定义使用泛型的静态方法,需要添加额外的泛型声明(将这个方法定义成泛型方法)
        * 即使静态方法要使用泛型类中已经声明过的泛型也不可以。
        * 如:public static void show(T t){..},此时编译器会提示错误信息:
             "StaticGenerator cannot be refrenced from static context"
        */
       public static <T> void show(T t){
  2.  
  3.   }
    }

3.2 泛型类型继承规则

1,对于泛型参数是继承关系的泛型类之间是没有继承关系的 2,泛型类可以继承其它泛型类,例如: public class ArrayList<E> extends AbstractList<E> 3,泛型类的继承关系在使用中同样会受到泛型类型的影响

  1. /**
    * Author:lin 2020/7/12 21:55
    * <p>
    * Description: 泛型继承规则测试类
    */
    public class GenericInherit<T> {
       private T data1;
       private T data2;
  2.  
  3.    public T getData1() {
           return data1;
      }
  4.  
  5.    public void setData1(T data1) {
           this.data1 = data1;
      }
  6.  
  7.    public T getData2() {
           return data2;
      }
  8.  
  9.    public void setData2(T data2) {
           this.data2 = data2;
      }
  10.  
  11.    public static <V> void setData2(GenericInherit<Father> data2) {
  12.  
  13.   }
  14.  
  15.    public static void main(String[] args) {
    //       Son 继承自 Father
           Father father = new Father();
           Son son = new Son();
           GenericInherit<Father> fatherGenericInherit = new GenericInherit<>();
           GenericInherit<Son> sonGenericInherit = new GenericInherit<>();
           SubGenericInherit<Father> fatherSubGenericInherit = new SubGenericInherit<>();
           SubGenericInherit<Son> sonSubGenericInherit = new SubGenericInherit<>();
  16.  
  17.        /**
            * 对于传递的泛型类型是继承关系的泛型类之间是没有继承关系的
            * GenericInherit<Father> 与GenericInherit<Son> 没有继承关系
            * Incompatible types.
            */
           father = new Son();
    //       fatherGenericInherit=new GenericInherit<Son>();
  18.  
  19.        /**
            * 泛型类可以继承其它泛型类,例如: public class ArrayList<E> extends AbstractList<E>
            */
           fatherGenericInherit=new SubGenericInherit<Father>();
  20.  
  21.        /**
            *泛型类的继承关系在使用中同样会受到泛型类型的影响
            */
           setData2(fatherGenericInherit);
    //       setData2(sonGenericInherit);
           setData2(fatherSubGenericInherit);
    //       setData2(sonSubGenericInherit);
  22.  
  23.   }
  24.  
  25.    private static class SubGenericInherit<T> extends GenericInherit<T> {
  26.  
  27.   }

3.3 虚拟机是如何实现泛型的

Java泛型是Java1.5之后才引入的,为了向下兼容。Java采用了C++完全不同的实现思想。Java中的泛型更多的看起来像是编译期用的 Java中泛型在运行期是不可见的,会被擦除为它的上级类型。如果是没有限定的泛型参数类型,就会被替换为Object.

  1. GenericClass<String> stringGenericClass=new GenericClass<>();
    GenericClass<Integer> integerGenericClass=new GenericClass<>();

C++中GenericClass<String>和GenericClass<Integer>是两个不同的类型 Java进行了类型擦除之后统一改为GenericClass<Object>

  1. /**
    * Author:lin 2020/7/12 21:55
    * <p>
    * Description:泛型原理测试类
    */
    public class GenericTheory {
       public static void main(String[] args) {
           Map<String, String> map = new HashMap<>();
           map.put("Key", "Value");
           System.out.println(map.get("Key"));
           GenericClass<String, String> genericClass = new GenericClass<>();
           genericClass.put("Key", "Value");
           System.out.println(genericClass.get("Key"));
      }
  2.  
  3.    public static class GenericClass<K, V> {
           private K key;
           private V value;
  4.  
  5.        public void put(K key, V value) {
               this.key = key;
               this.value = value;
          }
  6.  
  7.        public V get(V key) {
               return value;
          }
      }
  8.  
  9.    /**
        * 类型擦除后GenericClass2<Object>
        * @param <T>
        */
       private class GenericClass2<T> {
  10.  
  11.   }
  12.  
  13.    /**
        * 类型擦除后GenericClass3<ArrayList>
        * 当使用到Serializable时会将相应代码强制转换为Serializable
        * @param <T>
        */
       private class GenericClass3<extends ArrayList & Serializable> {
  14.  
  15.   }
    }

对应的字节码文件

  1. public static void main(String[] args) {
           Map<String, String> map = new HashMap();
           map.put("Key", "Value");
           System.out.println((String)map.get("Key"));
           GenericTheory.GenericClass<String, String> genericClass = new GenericTheory.GenericClass();
           genericClass.put("Key", "Value");
           System.out.println((String)genericClass.get("Key"));
      }

4.学以致用

1,泛型解析JSON数据封装

api返回的json数据

  1. {
       "code":200,
       "msg":"成功",
       "data":{
           "name":"Lin",
           "email":"10086"
      }
    }
    BaseResponse .java
  1. /**
    * Author:lin 2020/7/12 21:55
    * <p>
    * Description: 接口数据接收基类
    */
    public class BaseResponse {
  2.  
  3.    private int code;
       private String msg;
  4.  
  5.    public int getCode() {
           return code;
      }
  6.  
  7.    public void setCode(int code) {
           this.code = code;
      }
  8.  
  9.    public String getMsg() {
           return msg;
      }
  10.  
  11.    public void setMsg(String msg) {
           this.msg = msg;
      }
    }
    UserResponse.java
  1. /**
    * Author:lin 2020/7/12 21:55
    * <p>
    * Description: 用户信息接口实体类
    */
    public class UserResponse<T> extends BaseResponse {
       private T data;
  2.  
  3.    public T getData() {
           return data;
      }
  4.  
  5.    public void setData(T data) {
           this.data = data;
      }
    }

2,泛型+反射实现巧复用工具类

  1. /**
    * Author:lin 2020/7/12 21:55
    * <p>
    * Description: 泛型相关的工具类
    */
    public class GenericUtils {
  2.  
  3.    public static class Movie {
           private String name;
           private Date time;
  4.  
  5.        public String getName() {
               return name;
          }
  6.  
  7.        public Date getTime() {
               return time;
          }
  8.  
  9.        public Movie(String name, Date time) {
               this.name = name;
               this.time = time;
          }
  10.  
  11.        @Override
           public String toString() {
               return "Movie{" + "name='" + name + '\'' + ", time=" + time + '}';
          }
      }
  12.  
  13.    public static void main(String[] args) {
           List<Movie> movieList = new ArrayList<>();
           for (int i = 0; i < 5; i++) {
               movieList.add(new Movie("movie" + i, new Date()));
          }
           System.out.println("排序前:" + movieList.toString());
  14.  
  15.        GenericUtils.sortAnyList(movieList, "name", true);
           System.out.println("按name正序排:" + movieList.toString());
  16.  
  17.        GenericUtils.sortAnyList(movieList, "name", false);
           System.out.println("按name逆序排:" + movieList.toString());
      }
  18.  
  19.    /**
        * 对任意集合的排序方法
        * @param targetList 要排序的实体类List集合
        * @param sortField 排序字段
        * @param sortMode   true正序,false逆序
        */
       public static <T> void sortAnyList(List<T> targetList, final String sortField, final boolean sortMode) {
           if (targetList == null || targetList.size() < 2 || sortField == null || sortField.length() == 0) {
               return;
          }
           Collections.sort(targetList, new Comparator<Object>() {
               @Override
               public int compare(Object obj1, Object obj2) {
                   int retVal = 0;
                   try {
                       // 获取getXxx()方法名称
                       String methodStr = "get" + sortField.substring(0, 1).toUpperCase() + sortField.substring(1);
                       Method method1 = ((T) obj1).getClass().getMethod(methodStr, null);
                       Method method2 = ((T) obj2).getClass().getMethod(methodStr, null);
                       if (sortMode) {
                           retVal = method1.invoke(((T) obj1), null).toString().compareTo(method2.invoke(((T) obj2), null).toString());
                      } else {
                           retVal = method2.invoke(((T) obj2), null).toString().compareTo(method1.invoke(((T) obj1), null).toString());
                      }
                  } catch (Exception e) {
                       System.out.println("List<" + ((T) obj1).getClass().getName() + ">排序异常!");
                       e.printStackTrace();
                  }
                   return retVal;
              }
          });
      }
    }

3,Gson库中的泛型的使用-TypeToken

  1. /**
    * Author:Jay On 2019/5/11 22:11
    * <p>
    * Description: Gson库中的泛型使用
    */
    public class GsonGeneric {
       public static class Person {
           private String name;
           private int age;
  2.  
  3.        public Person(String name, int age) {
               this.name = name;
               this.age = age;
          }
  4.  
  5.        @Override
           public String toString() {
               return "Person{" +
                       "name='" + name + '\'' +
                       ", age=" + age +
                       '}';
          }
      }
  6.  
  7.    public static void main(String[] args) {
           Gson gson = new Gson();
           List<Person> personList = new ArrayList<>();
           for (int i = 0; i < 5; i++) {
               personList.add(new Person("name" + i, 18 + i));
          }
           // Serialization
           String json = gson.toJson(personList);
           System.out.println(json);
           // Deserialization
           Type personType = new TypeToken<List<Person>>() {}.getType();
           List<Person> personList2 = gson.fromJson(json, personType);
           System.out.println(personList2);
      }
    }

发哥讲

如果你觉得文章还不错,就请点击右上角选择发送给朋友或者转发到朋友圈~

● 扫码关注公众号

20、Java 泛型的更多相关文章

  1. 浅析Java 泛型

    泛型是JavaSE5引入的一个新概念,但是这个概念在编程语言中却是很普遍的一个概念.下面,根据以下内容,我们总结下在Java中使用泛型. 泛型使用的意义 什么是泛型 泛型类 泛型方法 泛型接口 泛型擦 ...

  2. 18.Java泛型

    1.为什么需要泛型 List list1=new ArrayList(Arrays.asList(new String("string"),new Integer(20))); S ...

  3. 【Java心得总结四】Java泛型下——万恶的擦除

    一.万恶的擦除 我在自己总结的[Java心得总结三]Java泛型上——初识泛型这篇博文中提到了Java中对泛型擦除的问题,考虑下面代码: import java.util.*; public clas ...

  4. Java泛型学习笔记 - (七)浅析泛型中通配符的使用

    一.基本概念:在学习Java泛型的过程中, 通配符是较难理解的一部分. 主要有以下三类:1. 无边界的通配符(Unbounded Wildcards), 就是<?>, 比如List< ...

  5. 全面总结Java泛型

    本文对Java泛型进行了全面的总结.文章内容包括普通泛型.通配符.受限泛型.泛型接口.泛型方法.返回泛型类型实例等等. 虽然Scala创始人Martin Odersky说当年正是因为Java泛型的丑陋 ...

  6. Java学习笔记(二一)——Java 泛型

    [前面的话] 最近脸好干,掉皮,需要买点化妆品了. Java泛型好好学习一下. [定义] 一.泛型的定义主要有以下两种: 在程序编码中一些包含类型参数的类型,也就是说泛型的参数只可以代表类,不能代表个 ...

  7. Java 泛型(Generics)

    Generics, 类似C++中的模版. 允许在定义类和接口的时候使用类型参数(type parameters), 声明的类型参数在使用的时候用具体的类型来替换. 如 ArrayList<Str ...

  8. java泛型 8 泛型的内部原理:类型擦除以及类型擦除带来的问题

    参考:java核心技术 一.Java泛型的实现方法:类型擦除 前面已经说了,Java的泛型是伪泛型.为什么说Java的泛型是伪泛型呢?因为,在编译期间,所有的泛型信息都会被擦除掉.正确理解泛型概念的首 ...

  9. Java泛型介绍!!!

    Java总结篇系列:Java泛型  转自:http://www.cnblogs.com/lwbqqyumidi/p/3837629.html 一. 泛型概念的提出(为什么需要泛型)? 首先,我们看下下 ...

随机推荐

  1. scrapy 源码解析 (二):启动流程源码分析(二) CrawlerProcess主进程

    CrawlerProcess主进程 它控制了twisted的reactor,也就是整个事件循环.它负责配置reactor并启动事件循环,最后在所有爬取结束后停止reactor.另外还控制了一些信号操作 ...

  2. Alexnet网络结构

    最近试一下kaggle的文字检测的题目,目前方向有两个ssd和cptn.直接看看不太懂,看到Alexnet是基础,今天手写一下网络,记录一下啊. 先理解下Alexnet中使用的原件和作用: 激活函数使 ...

  3. 开源利器分享:BitBar 坐看今天你的项目涨了多少 star

    今天开头我想叨叨几句,我个人最近的感受.在这个信息爆炸,互联网的时代里.我的周遭总是充斥者着各种让人能产生焦虑的信息, 我不知道有没有小伙伴和我一样,看到各种神通广大.游戏人生的大侠,低头看看自己当前 ...

  4. Python Hacking Tools - Password Sniffing

    Password Sniffing with Scapy 1. Download and install the Scapy first. pip install scapy https://scap ...

  5. ATX 学习 (四)-atxserver2

    ATXSERVER2 一.main()文件启动 1.首先通过parse_args返回一个Namespace作一些配置,登录页html在SimpleLoginHandler这个里边写着,2.接着通过db ...

  6. python监控服务器应用日志,推送钉钉机器人,实时关注日志异常

    生产环境多台服务器上部署了多个应用,日志出现报错时,无法及时反馈到开发人员.部署一个大型的运维监控应用,不但耗资源,而且配置也不简单. 简简单单写个python脚本来监控服务器日志就简单多了,废话不多 ...

  7. Lua骚操作——三元条件运算符

    本文地址:https://www.cnblogs.com/oberon-zjt0806/p/13337577.html 本文参考了这篇文章 三元运算符 (如果您已经了解什么是三元运算符,请大胆第前往下 ...

  8. java io流根据url读取图片

    //获取图片大小 public void readFileSize(String url,HttpServletRequest request){ //根路径 File file = new File ...

  9. DJANGO-天天生鲜项目从0到1-009-购物车-Ajax实现添加至购物车功能

    本项目基于B站UP主‘神奇的老黄’的教学视频‘天天生鲜Django项目’,视频讲的非常好,推荐新手观看学习 https://www.bilibili.com/video/BV1vt41147K8?p= ...

  10. Django Models随机获取指定数量数据方法

    方法一:新增models的Manager方法 下面就直接发代码了 class RandomManager(models.Manager): def get_queryset(self): return ...