JAVA语言基础小小总结

1.接口

1.1 接口是什么

  • Java里的interface, 就是抽象方法和常量值的集合,与class平行

  • [public] interface interfaceName[extends<Superinterface_list>]{
        public static final members
            
        public abstract methods
    }
    

1.2 接口的定义、实现和继承

  • 定义:

    • 接口定义在同名字的java文件内:可以用public修饰;

    • 接口不是定义在同名字的java文件内:不能带任何权限修饰符,且只能被同1个包内的类访问,其他类不能访问。

    • 跟外部类一样,外部接口不能用private 和 protected来修饰。

    • 接口的所有变量都是public static final,可以省略不写。

    • 接口的所有方法都是public abstract,也可以省略不写。而抽象类允许非抽象方法的存在,这是接口和抽象类的区别之一。

    • 接口里没有this指针,没有构造函数。

    • java8之后允许有default、static的方法和方法体。

    • 附java修饰符:

      在这里插入图片描述

  • 实现:

    • 实现接口的非抽象类必须重写接口的所有方法。一个抽象类实现接口,可以不重写接口的方法,而一个非抽象类继承这个抽象类的话,那么这个非抽象类就要重写接口的所以方法。

    • 多态(与继承的多态类似):

      public class Interface_1{
      	public static void f(){
      		It_1 a = new It_class(); // It_1为接口,It_class为实现了这个接口的类
      		a.print();
      	}
      }
      
    • 一个类可以实现多个接口。

  • 继承:一个接口可以继承多个接口。

1.3 为什么会出现接口

  • 实现多态
  • 实现多继承

2. 容器

  • java容器分类图(实线为实现类):

    在这里插入图片描述

在这里插入图片描述

  • ArrayList LinkedList Vector
    底层原理 数组 双向链表 数组
    安全性 非线程安全 非线程安全 相对线程安全,很多方法使用了sychronized
    元素 允许重复,允许为空 允许重复,允许为空 允许重复,允许为空
HashSet TreeSet HashMap ConcurrentHashMap TreeMap
底层原理 HashMap TreeMap Entry数组+链表+红黑树 与HashMap相同 红黑树
安全性 非线程安全 非线程安全 非线程安全 线程安全(分段锁,效率比Hashtable高) 非线程安全
元素 忽略重复 有序 无序 无序 有序

3. 异常

在这里插入图片描述

移步:https://www.runoob.com/java/java-exceptions.html

4. 泛型

  • 常用方式:泛型类、泛型接口和泛型方法。

  • 泛型类:

    public class genericClass <E> {
        private E value;
        public void setValue(E ele){
            this.value = ele;
        }
        public E getValue(){
            return value;
        }
    }
    
  • 泛型接口:

    public interface Generator<T> {
        public T next();
    }
    
  • 泛型方法:

    public <E> E genericFunc(E element){
            return element;
    }
    

5. 反射

5.1 反射是什么

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

5.2 反射的用处/用法

  • 有博主总结的很好的,具体移步:https://www.cnblogs.com/yonyong/p/9429079.html

  • 获取Class对象的三种方式(Class类没有公共构造方法)

    • 通过Object中的getObject()方法

      Person p = new Person();
      Class c = p.getClass();
      
    • 通过 类名.class 获取到字节码文件对象(任意数据类型都具备一个class静态属性,看上去要比第一种方式简单)

      Class c2 = Person.class;
      
    • 通过Class类中的方法(将类名作为字符串传递给Class类中的静态方法forName即可)

      Class c3 = Class.forName("Person");
      

5.3 为什么会有反射

  • 为了代码简洁,提高代码的复用率,外部调用方便,源代码,反编译都能看到。
  • 有博主总结的很好的,具体移步:https://www.cnblogs.com/yonyong/p/8595737.html

6. 注解(Annotation)

6.1 注解是什么

  • Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。
  • Java 语言中的类、方法、变量、参数和包等都可以被标注。
  • 和 Javadoc 不同,Java 标注可以通过反射获取标注内容。
  • 在编译器生成类文件时,标注可以被嵌入到字节码中。
  • Java 虚拟机可以保留标注内容,在运行时可以获取到标注内容 。
  • 它也支持自定义 Java 标注。

6.2 注解的用处/用法

  • 注解的定义

    public @interface TestAnnotation {
    }
    //它的形式跟接口很类似,不过前面多了一个 @ 符号。上面的代码就创建了一个名字为 TestAnnotaion 的注解。
    
  • 注解的应用

    @TestAnnotation
    public class Test {
    }
    //创建一个类 Test,然后在类定义的地方加上 @TestAnnotation 就可以用 TestAnnotation 注解这个类了。
    
  • 元注解

    • 元注解是一种基本注解,但是它能够应用到其它的注解上面。
    • @Retention:Retention即保留期,当 @Retention 应用到一个注解上的时候,它解释说明了这个注解的的存活时间。取值如下:
      • RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。
      • RetentionPolicy.CLASS 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中。
      • RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们。
    • @Documented:它的作用是能够将注解中的元素包含到 Javadoc 中去。
    • @Target:指定了注解运用的地方。取值如下:
      • ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
      • ElementType.CONSTRUCTOR 可以给构造方法进行注解
      • ElementType.FIELD 可以给属性进行注解
      • ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
      • ElementType.METHOD 可以给方法进行注解
      • ElementType.PACKAGE 可以给一个包进行注解
      • ElementType.PARAMETER 可以给一个方法内的参数进行注解
      • ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举
    • @Inherited:如果一个父类被 @Inherited 注解过的注解进行注解的话,而且它的子类没有被任何注解应用的话,那么这个子类就继承了父类的注解。
    • @Repeatable:JAVA8新特性,注解的值可以同时取多个。
  • 注解的属性

    • 注解的属性也叫做成员变量。注解只有成员变量,没有方法。注解的成员变量在注解的定义中以“无形参的方法”形式来声明,其方法名定义了该成员变量的名字,其返回值定义了该成员变量的类型。

      @Target(ElementType.TYPE)
      @Retention(RetentionPolicy.RUNTIME)
      public @interface TestAnnotation {
          int id();
          String msg();
      }
      //上面代码定义了 TestAnnotation 这个注解中拥有 id 和 msg 两个属性。在使用的时候,我们应该给它们进行赋值。
      
      //赋值的方式是在注解的括号内以 value=”” 形式,多个属性之前用 ,隔开。
      @TestAnnotation(id=3,msg="hello annotation")
      public class Test {
      }
      
    • 需要注意的是,在注解中定义属性时它的类型必须是 8 种基本数据类型外加 类、接口、注解及它们的数组

      //注解中属性可以有默认值,默认值需要用 default 关键值指定。比如:
      @Target(ElementType.TYPE)
      @Retention(RetentionPolicy.RUNTIME)
      public @interface TestAnnotation {
          public int id() default -1;
          public String msg() default "Hi";
      }
      //TestAnnotation 中 id 属性默认值为 -1,msg 属性默认值为 Hi。它可以这样应用:
      @TestAnnotation()
      public class Test {}
      //因为有默认值,所以无需要再在 @TestAnnotation 后面的括号里面进行赋值了,这一步可以省略.
      
      //另外,还有一种情况。如果一个注解内仅仅只有一个名字为 value 的属性时,应用这个注解时可以直接接属性值填写到括号内。
      public @interface Check {
          String value();
      }
      //上面代码中,Check 这个注解只有 value 这个属性。所以可以这样应用:
      @Check("hi")
      int a;
      
      //最后,还需要注意的一种情况是一个注解没有任何属性。比如:
      public @interface Perform {}
      //那么在应用这个注解的时候,括号都可以省略。
      @Perform
      public void testMethod(){}
      
  • JAVA预置的注解

    • @Deprecated:这个元素是用来标记过时的元素,想必大家在日常开发中经常碰到。编译器在编译阶段遇到这个注解时会发出提醒警告,告诉开发者正在调用一个过时的元素比如过时的方法、过时的类、过时的成员变量。

    • @Override:提示子类要复写父类中被 @Override 修饰的方法。

    • @SuppressWarnings:阻止警告的意思。之前说过调用被 @Deprecated 注解的方法后,编译器会警告提醒,而有时候开发者会忽略这种警告,他们可以在调用的地方通过 @SuppressWarnings 达到目的。

      @SuppressWarnings("deprecation")
      
    • @SafeVarargs:参数安全类型注解。它的目的是提醒开发者不要用参数做一些不安全的操作,它的存在会阻止编译器产生 unchecked 这样的警告。

    • @FunctionalInterface:函数式接口注解,这个是 Java 1.8 版本引入的新特性。函数式编程很火,我们进行线程开发中常用的 Runnable 就是一个典型的函数式接口,它就被 @FunctionalInterface 注解。函数式接口可以很容易转换为 Lambda 表达式。

6.3 为什么会出现注解

  • 注解主要给编译器及工具类型的软件用的。
  • 注解的提取需要借助于 Java 的反射技术,反射比较慢,所以注解使用时也需要谨慎计较时间成本。

7. I/O

7.1 JAVA中有几种类型的流?

  • 字符流和字节流

在这里插入图片描述

  • 字节流继承inputStream和OutputStream
    字符流继承自InputSteamReader和OutputStreamWriter

  • 总体结构图:

    在这里插入图片描述

7.2 字节流和字符流怎么选择?两者的区别?

  • 大多数情况下使用字节流会更好,IO 操作都是直接操作磁盘文件,所以这些流在传输时都是以字节的方式进行的,图片等都是按字节存储的。
  • 如果对于操作需要通过 IO 在内存中频繁处理字符串的情况使用字符流会好些,因为字符流具备缓冲区,提高了性能。
  • 缓冲区就是一段特殊的内存区域,很多情况下当程序需要频繁地操作一个资源(如文件或数据库)则性能会很低,所以为了提升性能就可以将一部分数据暂时读写到缓存区,以后直接从此区域中读写数据即可,这样就显著提升了性。对于 Java 字符流的操作都是在缓冲区操作的,所以如果我们想在字符流操作中主动将缓冲区刷新到文件则可以使用 flush() 方法操作。
  • 字节流和字符流的区别:字节流的操作不会经过缓冲区(内存)而是直接操作文本本身的,而字符流的操作会先经过缓冲区(内存)然后通过缓冲区再操作文件。

7.3 什么是JAVA序列化,如何实现JAVA序列化?

  • 序列化就是将对象的内容进行流化。可以对流化后的对象进行读写操作,可以将流化后的对象传输于网络之间
  • 序列化的实现:将需要被序列化的类实现Serialize接口,没有需要实现的方法,此接口只是为了标注对象可被序列化的。然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,再使用ObjectOutputStream对象的write(Object obj)方法就可以将参数obj的对象写出。

7.4 流一般需要不需要关闭,如果关闭的话在用什么方法,一般要在那个代码块里面关闭比较好?

  • 流一旦打开就必须关闭,使用close方法,放入finally语句块中(finally 语句一定会执行)。

  • 序列化的实现:将需要被序列化的类实现Serialize接口,没有需要实现的方法,此接口只是为了标注对象可被序列化的。然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,再使用ObjectOutputStream对象的write(Object obj)方法就可以将参数obj的对象写出。

--------本篇完--------

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章