zoukankan      html  css  js  c++  java
  • java基础知识总结

    java在安卓的开发中是非常重要的,所以今天我总结了一下java的基础知识,当然,还有一些没有总结完,例如网络编程,io流等,将会在下一篇博文中写出。

    概述

    javac :负责的是编译的部分

    java :负责运行的部分.会启动 jvm.加载运行时所需的类库,并对 class 文件进行执行

    语法规则

    数据类型

    1 1 ): 基本数据类型:byte(1个字节)、short(2)、int(4)、long(8)、float(4)、double(8)、char(2)、boolean。

    1个字节占8位

    2 2 ): 引用数据 类型: 数组、类、接口。

    运算符

    + - / % %:任何整数模 2 不是 0 就是 1,所以只要改变被模数就可以实现开关运算

    &: 只有两边都为 true 结果是 true。否则就是 false。

    |:只要两边都为 false 结果是 false,否则就是 true

    & 和 && 区别: & :无论左边结果是什么,右边都参与运算。
    &&: 短路与,如果左边为 false,那么右边不参数与运算。

    | 和 || 区别:|:两边都运算。
    || : 短路或,如果左边为 true,那么右边不参与运算。

    ++X(–X)表示在使用x之前,先使x的值增(减)1

    语句

    If switch do while while for

    当判断固定个数的值的时候,建议使用 switch,效率相对较高。

    当判断数据范围,获取判断运算结果 boolean 类型时,需要使用 if。

    当某些语句需要执行很多次时,就用循环结构,建议使用 for。因为 for 循环完毕,变量在内存中释放。

    函数

    重载的定义是:在一个类中,如果出现了两个或者两个以上的同名函数,只要它们的参数的个数,或者参数的
    类型不同,即可称之为该函数重载了。
    如何区分重载:当函数同名时,只看参数列表。和返回值类型没关系。

    数据

    // 二分查找法。必须有前提: 数组中的元素要有序。
    public static int halfSeach_2(int[] arr,int key){
    int min,max,mid;
    min = 0;
    max = arr.length-1;
    mid = (max+min)>>1; //(max+min)/2;
    while(arr[mid]!=key){
    if(key>arr[mid]){
    min = mid + 1;
    }
    else if(key<arr[mid])
    max = mid - 1;
    if(max<min)
    return -1;
    mid = (max+min)>>1;
    }
    return mid;
    }
    

    java 分了 5 5 片内存。
    1 :寄存器。2 :本地方法区。3 :方法区。4 :栈。5 :堆。

    栈:存储的都是局部变量 ( 函数中定义的变量,函数上的参数,语句中的变量 );
    只要数据运算完成所在的区域结束,该数据就会被释放。后进先出。
    
    堆:用于存储数组和对象,也就是 实体。啥是实体啊?就是用于封装多个数据的。
    1 :每一个实体都有内存首地址值。
    2 :堆内存中的变量都有默认初始化值。因为数据类型不同,值也不一样。
    3 :垃圾回收机制。
    

    面向对象

    属性是用于存储数据的 , 直接被访问,容易出现安全隐患 , 所以,类中的属性通
    常被私有化,并对外提供公共的访问方法。
    这个方法一般有两个,规范写法:对于属性 xxx ,可以使用 setXXX(),getXXX() 对其进行操作

    主函数的存在,仅为该类是否需要独立运行 , 如果不需要,主函数是不用定义的。
    主函数的解释:保证所在类的独立运行,是程序的入口,被 jvm 调用。

    构造函数是在对象创建时,就被调用,用于初始化, 而且初始化动作只执行一次。
    一般函数,是对象创建后,需要调用才执行,可以被调用多次。

    封装

    将不需要对外提供的内容都隐藏起来,把属性都隐藏,提供公共方法对其访问。

    this

    用 this 调用构造函数,必须定义在构造函数的第一行。因为构造函数是用于初始化的,所以初
    始化动作一定要执行。 否则编译失败。

    static

    关键字,是一个修饰符 , 用于修饰成员( ( 成员变量和成员函数) ) 
    
    静态方法只能访问静态成员,不可以访问非静态成员。
    静态方法中不能使用  this ,super  关键字。
    成员变量可以称为对象的特有数据,静态变量称为对象的共享数据。
    静态代码块、构造代码块、构造函数同时存在时的执行顺序: 静态代码块 à 构造代码块 à 构造函数
    

    单例设计模式

    保证一个类在内存中的对象唯一性。
    步骤:
    1 1 ,因为创建对象都需要构造函数初始化 ,只要将本类中的构造函数私有化,其他程序就无法 再 创建
    该类对象;
    2 2 ,就在类中创建一个本类的对象 ;
    3 3 ,定义一个方法,。 返回该对象,让其他程序可以通过方法就得到本类对象。 (作用:可控)
    代码体现:
    1 1 ,私有化构造函数 ;
    2 2 ,创建私有并静态的本类对象 ;
    3 3 ,定义公有并静态的方法,返回该对象

    //饿汉式
    class Single{
    private Single(){} // 私有化构造函数。
    private static Single s = new Single(); // 创建私有并静态的本类对象。
    public static Single getInstance(){ // 定义公有并静态的方法,返回该对象。
    return s;
    }
    }
    
    //懒汉式:延迟加载方式。
    class Single2{
    private Single2(){}
    private static Single2 s = null;
    public static Single2 getInstance(){
    if(s==null)
    s = new Single2();
    return s;
    }
    }
    

    继承

    java 中对于继承,java 只支持单继承。java 虽然不直接支持多继承,但是保留了这种多继承机制,进行改良。
    java 支持多重继承。A 继承 B B 继承 C C 继承 D。

    子类在进行对象初始化时,先调用父类的构造函数,这就是子类的实例化过程。

    super()和 和 this() 不可以同时出现的构造函数中。

    在方法覆盖时,注意两点:
    1:子类覆盖父类时,必须要保证,子类方法的权限必须大于等于父类方法权限可以实现继承。否则,编译
    失败。
    2:覆盖时,要么都静态,要么都不静态。 (静态只能覆盖静态,或者被静态覆盖)

    final

    可以修饰类,方法,变量。不可以被继承、覆盖。

    抽象类

    抽象类的特点:
    1 1 : 抽象方法只能定义在 抽象类中 , 抽象类和抽象方法必须由 t abstract 关键字修饰 (可以描述类和
    ) 方法,不可以描述变量) 。
    2 2 : 抽象方法只定义方法声明,并不定义方法实现。
    3 3 : 抽象类不可以被创建对象( ( 实例化) ) 。
    4 4 : 只有通过子类继承抽象类并覆盖了抽象类中的 所有 抽象方法后,该子类 才 可以实例化。否则,
    该子类还是一个抽象类。

    抽象类可以大一非抽象方法,抽象类中有构造函数。

    接口

    接口中有抽象方法,接口不可以实例化。 接口的子类必须实现了接口 中 所有的抽象方法后,该子类才可以实例化。否则,该子类还是一个抽象类。

    类与类之间存在着继承关系,类与接口中间存在的是 实现关系。
    继承用 extends ; 实现用 implements

    多态

    体现: 父类引用或者接口的引用指向了自己的子类对象。 //Animal a = new Cat();

    instanceof ;// 判断对象是否实现了指定的接口或继承了指定的类

    Object

    public boolean equals(Object obj){
    if(!(obj instanceof Person))
    return false;
    Person p = (Person)obj;
    return this.age == p.age;
    }
    

    通常 equals , toString , hashCode ,在应用中都会被复写 , 建立具体对象的特有的内容。

    内部类

    如果 A 类需要直接访问 B 类中的成员,而 B 类又需要建立 A 类的对象。这时,为了方便设计和访问,
    直接将 A 类定义在 B 类中。就可以了。A 类就称为 内部类。内部类可以直接访问外部类中的成员。而外部类想要
    访问内部类,必须要建立内部类的对象。

    class Outer{
    int num = 4; 
    class Inner {
    void show(){
    System.out.println("inner show run "+num);
    }
    }
    public void method(){
    Inner in = new Inner();//创建内部类的对象。
    in.show();//调用内部类的方法。
    }
    }
    

    匿名内部类:
    当函数的参数是接口类型引用时,如果接口中的方法不超过 3 个。可以通过匿名内部类来完成参数的传递。

    异常

    通过 throws 关键字完成, 格式: throws 异常类名, , 异常类名

    throw 用于抛出异常对象,后面跟的是异常对象;throw 用在函数内。
    throws 用于抛出异常类,后面跟的异常类名,可以跟多个,用逗号隔开。throws 用在函数上。

    运行时异常,其中 Exception 有一个特殊的子类 RuntimeException,以及 RuntimeException 的子类是运
    行异常,也就说这个异常是编译时不被检查的异常。

    finally 很有用,只要用户关闭资源。无论是否发生异常,资源都必须进行关闭。
    System.exit(0); //退出 jvm,只有这种情况 finally 不执行。

    常见 异常 :
    1、脚标越界异常(IndexOutOfBoundsException)包括数组、字符串;
    空指针异常(NullPointerException)
    2、类型转换异常:ClassCastException
    3、不支持操作异常;

    常见的软件包:

    java.lang : language java 的核心包,Object System String Throwable jdk1.2 版本后,该
    包中的类自动被导入。

    java.awt : 定义的都是用于 java 图形界面开发的对象。

    javax.swing: : 提供所有的 windows 桌面应用程序包括的控件, 比如: Frame , Dialog, Table, List
    等等, , 就是 java 的图形界面库 。

    java.net : 用于 java 网络编程方面的对象都在该包中。

    java.io : input output 用于操作设备上数据的对象都在该包中。比如:读取硬盘数据,往硬盘写
    入数据。

    java.util a : java 的工具包,时间对象 , 集合框架。

    java.applet : application+let 端 客户端 a java 小程序。 server+let – > servlet 端 服务端 java
    小程序

    多线程

    创建线程:
    方法1:

    步骤:
    1,定义类继承 Thread 类;
    2,目的是复写 run 方法,将要让线程运行的代码都存储到 run 方法中;
    3,通过创建 Thread 类的子类对象,创建线程对象;
    4,调用线程的 start 方法,开启线程,并执行 run 方法。
    

    方法2:

    步骤:
    1,定义类实现 Runnable 接口。
    2,覆盖接口中的 run 方法(用于封装线程要运行的代码)。
    3,通过 Thread 类创建线程对象;
    4,将实现了 Runnable 接口的子类对象作为实际参数传递给 Thread 类中的构造函数。
    为什么要传递呢?因为要让线程对象明确要运行的 run 方法所属的对象。
    5,调用 Thread 对象的 start 方法。开启线程,并运行 Runnable 接口子类中的 run 方法。
    Ticket t = new Ticket();
    /*
    直接创建 Ticket 对象,并不是创建线程对象。
    因为创建对象只能通过 new Thread 类,或者 new Thread 类的子类才可以。
    所以最终想要创建线程。既然没有了 Thread 类的子类,就只能用 Thread 类。
    `*/`
    Thread t1 = new Thread(t); //创建线程。
    /*
    只要将 t 作为 Thread 类的构造函数的实际参数传入即可完成线程对象和 t 之间的关联
    为什么要将 t 传给 Thread 类的构造函数呢?其实就是为了明确线程要运行的代码 run 方法。
    `*/`
    t1.start();
    

    同步

    同步函数:其实就是将同步关键字定义在函数上,让函数具备了同步性。

    同步函数使用的锁是 this , 静态同步函数的锁是 该类的字节码文件对象。

    同步是隐示的锁操作,而 k Lock 对象是显示的锁操作,它的出现就替代了同步。

    API

    字符串

    parseInt(string,radix); //将给定的数转成指定的基数进制;
    在 在 5 jdk1.5  版本后,对基本数据类型对象包装类进行升级。在升级中,使用基本数据类型对象包装类可
    以像使用基本数据类型一样,进行运算。
    Integer i = new Integer(4); 5 //1.5  版本之前的写法;
    Integer i = 4;  // 自动装箱 ,5 1.5  版本后的写法;
    i = i + 5;
    //i 对象是不能直接和 5 相加的,其实底层先将 i 转成 int 类型,在和 5 相加。而转成 int 类型的操作是隐
    式的。 自动拆箱:拆箱的原理就是  i.intValue();i+5 运算完是一个 int 整数。
    

    集合框架

    1:对象封装数据,对象多了也需要存储。 集合用于存储对象。
    2:对象的个数确定可以使用数组,但是不确定怎么办?可以用集合。因为

    List接口

    List : 有序( ( 元素存入集合的顺序和取出的顺序一致) ) ,元素都有索引。元素可以重复。
    | | -- ArrayList : 底层的数据结构 是数组, , 线程不同步 ,A At rrayList 了 替代了  Vector , 查询元素的速
    度非常快。
    | | -- LinkedList : 底层的数据结构是链表 , 线程不同步 , 增删元素的速度非常快。
    | | -- Vector : 底层的数据结构就是数组 , 线程同步的 ,r Vector  无论查询和增删都巨慢。
    

    对于 t list 集合,底层判断元素是否相同,其实用的是元素自身的 s equals 方法完成的。所以建议
    元素都要复写 s equals

    LinkedList : 的特有方法。
    addFirst();
    addLast();
    在 jdk1.6 以后。
    offerFirst();
    offerLast();
    getFirst():获取链表中的第一个元素。如果链表为空,抛出 NoSuchElementException;
    getLast();
    在 jdk1.6 以后。
    peekFirst();获取链表中的第一个元素。如果链表为空,返回 null。
    peekLast();
    removeFirst():获取链表中的第一个元素,但是会删除链表中的第一个元素。如果链表为空,抛出
    NoSuchElementException
    removeLast();
    在 jdk1.6 以后。
    pollFirst();获取链表中的第一个元素,但是会删除链表中的第一个元素。如果链表为空,返回 null。
    pollLast();
    

    Set接口

    当元素的 hashCode 值相同时,才继续判断元素的 equals 是否为 true。

    TreeSet:
    用于对 Set 集合进行元素的指定顺序排序,排序需要依据元素自身具备的比较性。
    如果元素不具备比较性,在运行时会发生 n ClassCastException  异常。
    所以需要元素 实现 e Comparable  接口,强制让元素具备比较性, 复写 o compareTo  方法。
    

    Map集合

    – Hashtable :底层是哈希表数据结构,是线程同步的。不可以存储 null 键,null 值。

    – HashMap :底层是哈希表数据结构,是线程不同步的。可以存储 null 键,null 值。替代了 Hashtable.

    – TreeMap :底层是二叉树结构,可以对 map 集合中的键进行指定顺序的排序。

    把 把 p map 集合转成 t set 的方法

    Set keySet();
    Set entrySet(); //取的是键和值的映射关系。

    取出 p map  集合中所有元素的方式一 : keySet() 方法。
    可以将 map 集合中的键都取出存放到 set 集合中。对 set 集合进行迭代。迭代完成,再通过 get 方法对获取
    到的键进行值的获取。
    Set keySet = map.keySet();
    Iterator it = keySet.iterator();
    w w hile(it.hasNext()) { {
    Object key = it.next();
    Object value = map.get(key);
    System.out.println(key+":"+value);
    } }
    
    取出 p map  集合中所有元素的方式 二 : entry Set() 方法。
    Set entrySet = map.entrySet();
    Iterator it = entrySet.iterator();
    while(it.hasNext()) {
    Map.Entry me = (Map.Entry)it.next();
    System.out.println(me. getKey()+"::::"+me. getValue());
    

    使用集合的技巧:

    看到 Array 就是数组结构,有角标,查询速度很快。
    看到 link 就是链表结构:增删速度快,而且有特有方法。addFirst; addLast; removeFirst(); removeLast();
    getFirst();getLast();
    看到 hash 就是哈希表,就要想要哈希值,就要想到唯一性,就要想到存入到该结构的中的元素必须覆盖
    hashCode,equals 方法。
    看到 tree 就是二叉树,就要想到排序,就想要用到比较。
    比较的两种方式 :
    一个是  Comparable : 覆盖 o compareTo  方法 ;
    一个是  Comparator : 覆盖 e compare  方法。
    LinkedHashSet,LinkedHashMap:这两个集合可以保证哈希表有存入顺序和取出顺序一致,保证哈希表有序。
    集合什么时候用?
    当存储的是一个元素时,就用 Collection。当存储对象之间存在着映射关系时,就使用 Map 集合。
    保证唯一,就用  Set 。不保证唯一 , 就用  List
    

    双列集合 Map

    Map map = new HashMap();
    map.put("a", "aaa");
    //  传统方式:必须掌握这种方式
    Set entrys = map.entrySet(); // 1.获得所有的键值对 Entry 对象
    iter = entrys.iterator(); // 2.迭代出所有的 entry
    while(iter.hasNext()) {
    Map.Entry entry = (Entry) iter.next();
    String key = (String) entry.getKey(); // 分别获得 key 和 value
    String value = (String) entry.getValue();
    System.out.println(key + "=" + value);
    }
    

    泛型

    当类中的操作的引用数据类型不确定的时候,以前用的 t Object 来进行扩展的,现在可以用泛型来表示。这样可以避免强转的麻烦,而且将运行问题转移到的编译时期。

    class Tool<Q> {
    private Q obj;
    public void setObject(Q obj) {
    this.obj = obj;
    }
    public Q getObject() {
    return obj;
    }
    }
    

    Data和日历类

    将日期字符串转换成日期对象 :是 使用的就是 DateFormat 方法中的 Date parse(String source)

     public static void method(){
    Calendar c = Calendar.getInstance();
    System.out.println(c.get(Calendar.YEAR)+"年"+(c.get(Calendar.MONTH)+1)+"月"
    +getNum(c.get(Calendar.DAY_OF_MONTH))+"日"
    +"星期"+getWeek(c.get(Calendar.DAY_OF_WEEK)));
    }
    public static String getNum(int num){
    return num>9 ? num+"" : "0"+num;
    }
    public static String getWeek(int index){
    /*
    查表法:建立数据的对应关系.
    最好:数据个数是确定的,而且有对应关系。如果对应关系的一方,是数字,而且可以作为角标,那么可以
    通过数组来作为表。
    */
    String[] weeks = {"","日","一","二","三","四","五","六"};
    return weeks[index];
    }
    
  • 相关阅读:
    spring mvc + kafka实战
    springboot 实现文件下载功能
    vue前端文件下载
    父类和子类初始化顺序
    几种单例模式
    全链路压测注意点
    压力测试-ab
    压力测试-locust讲解
    Java httpClient 中get, post ,put(form-data & raw), delete方法使用
    RequestBody 和RequestEntity使用
  • 原文地址:https://www.cnblogs.com/xiaowangba/p/6314878.html
Copyright © 2011-2022 走看看