javaSE总结

  • (一),Java开发环境搭建:
  1. JDK下载并安装配置,官网下载太慢:这里给一个国内镜像(https://repo.huaweicloud.com/java/jdk/
  2. 下载JDK注意,学习可以下高版本,甚至多个版本,使用我这里就选择JDK1.8;
  3. 下载完成后基本就是下一步下一步:注意他有可能hi给你安装俩(一定要分清楚JDK安装目录和JRE安装目录:配置环境变量最好是JDK安装目录)
  4. 环境变量配置:右击电脑选中属性---选中高级系统设置----找到环境变量配置:
  5. 一般是配置两个:(新建一个变量:JAVA_HOME,变量的值是安装路径)(在path变量下:添加一个值:%JAVA_HOME%/bin)
  6. 打开cmd,输入:Java -version  弹出Java版本号说明配置成功。
  • (二),编写第一个Java程序:HelloWorld

 

 

 

 

  1. 理解  Javac     编译     HelloWorld.java文件     成为      字节码文件   (HelloWorld.class)
  2. 理解    Java     执行     字节码文件    是运行通过JVM实现。
  3. 理解   javaDoc   执行  Java字节码文件    可以命令行传参(main方法的参数传递),产生程序说明文档
  • (三)Java语言认识:

 

1.关键字:

概念:被java语言赋予了特殊含义的单词

 

特点:所有字母都小写

public  private  protected  package  import  class  interface extends  implements  abstract  static  final  finally  try   catch  new  void  throw  throws if  else for while  switch case default  break   continue  return do  true false  null  this  super  byte  short  int   long  float  double  char  boolean  instanceof  transient synchronized

2.标识符:

规则:(1)不能以数字开头  (2)不可以是关键字

由26个英文字母大小写,数字0~9,_  $ 组成

规范:类名、接口名、包名、方法名、变量名、常量名 

扩展:类名首字母大写的驼峰命名规则,变量和方法名都是首字母小写的驼峰命名规则。常量一般是全大写,下划线分割。

 

3.注释:

单行注释:两根下划线    //

多行注释: /*。。。。。*/

文档注释:/**   。。。。*/

    1. @author 标识一个类的作者 
    2. @deprecated 指名一个过期的类或成员
    3. @param 说明一个方法的参数 
    4. @return 说明返回值类型
    5. @since 标记当引入一个特定的变化时(JDK最低版本)
    6. @version 指定类的版本 
    7. @throws 指定可能抛出的异常

 

4.基本数据类型:

 

Boolean类型:true:占一位;false:占一位;

 

数值类型:

 

整数类型:

 

      • byte:占1个字节,范围:-128~127

      • short:占2个字节,范围:-32768~32767

      • int:占4个字节,范围:-2147483648~2147483647

      • long:占8个字节,范围:-9223372036854775808~9223372036854775807

 

浮点数类型:

 

      • float:占4个字节

      • double:占8个字节

 

字符类型:

 

    • char:占两个字节

 

 

5.引用数据类型:


类、接口、数组

 

 

6.运算符:
算数运算符 +  -  *  /  %  ++  --

 

逻辑运算符 &  |  !  ^  &&  ||

 

比较运算符 >  <   >=  <=  !=  ==

 

赋值运算符 =  +=  -=  *=  /=  %=

 

三元运算符(三目运算)  判断条件?值1:值2;

 

位运算:二进制进行运算 

 

<<(左移)  >>(右移)  >>>(无符号右移)  &(按位与)  |(按位或)  ~(反码)


7.流程控制

判断语句:

if...else....

循环语句:

for   while  do...while   foreach(高级for循环)

选择语句:

switch...case

8.Java内存分析

 

9.数组

概念:同一数据类型的集合,称为容器

声明数组:元素类型[] 数组名 = new  元素类型[数组长度];

获取数组长度:数组名.length

遍历:for、foreach

排序:冒泡排序、选择排序。。。。。

 

10.方法的重写和重载

重载:概念:一个类中可以有多个同名方法,只要参数列表不同即可

重写:概念:一个类继承某个类需要重写这个类的抽象方法。除了方法体什么都一样。

 

11.递归思想:

递归是“你可以在一个方法中再次调用你自己”;

递归调用必须在某些条件下结束,否则它们是死递归。递归调用不能有太多级别,否则堆栈将溢出。不能递归调用构造函数。

 

(四)面向对象的认识

类:对一类事物的统称。

对象:一类事物的实实在在存在的实体,称为实例。

面向对象的编程的关键:对类的设计

对类的设计其实就是定义类中的成员:

    1. 属性:成员变量
    2. 方法:成员方法
    3. 构造器(构造方法):初始化对象(在创建对象时对属性进行赋值)
    4. 内部类 5.代码块

 

***********************************【面向对象的三大特征】********************************************

封装:私有化属性,公有方法。

将属性进行私有化,提供属性所对应的set  get 方法,提升属性赋值的合理性。

继承:子承父业

使用extends让类与类之间产生继承关系

      特性:重写

继承的出现提供了多态的前提

多态:一类事物的多种表现形态

前提:1.类与类之间必须有继承关系 

子类需要重写父类中的方法
父类的引用指向子类的对象==>向上转型==>自动类型提升

如果在多态中想使用子类特有的成员时:向下转型==>强转

 

抽象类:

被abstract修饰的类就是抽象类,包含有抽象方法的类必须是抽象类。

抽象类为了继承而诞生
抽象类不可以创建对象
抽象类具有强制性


接口:

特殊的抽象类,看成对程序的功能扩展,看成规则。

接口与类是平级关系
声明接口使用:interface
接口中的属性:public  static  final 进行修饰
接口中的方法:public  abstract 进行修饰
类与接口是实现关系:implements  类:实现类

异常:

 

 

 

 

 

处理异常的方式:

捕获异常: 

 

try{  尝试执行可能会发生异常的代码

 

}catch(异常类型的参数){如果发生异常就将异常对象捕获

 

}finally{一定会执行到的代码块,通常用来关闭资源

 

}

 

抛出异常:

使用throws在方法声明处声明异常
使用throw在方法的内部抛出异常对象


自定义异常:

 

声明一个类继承Exception或者Throwable
如果想要提示异常原因,必须在子类的构造器中将父类的带message的构造器指定出来。
在发生该异常的情况下使用throw抛出该异常对象
在抛出该异常的方法声明处声明该异常类型
 

************集合:******************************

 

 

 首先 List 和 Set 是 Collection 接口的子接口,而 Map 是独立的一个接口,与 Collection 无关

  • List:有序,可重复(有序是指存储顺序跟输入的一样,而不是说按某种排序方法排序的)。实现的类有:ArrayList、LinkedList、Vector。
  • Set:无序,唯一(无序是指存储顺序跟输入的不一样,而不是说按某种排序方法排序的)。实现的类有:HashSet、TreeSet。
  • Map:使用键值对存储。Map 会维护与 Key 有关联的值。两个 Key 可以引用相同的对象,但是 Key 不能重复。

  ArrayList 与 LinkedList 和Vector的区别?

ArrayList
优点: 底层数据结构是数组,查询快,增删慢。
缺点: 线程不安全,效率高
Vector
优点: 底层数据结构是数组,查询快,增删慢。
缺点: 线程安全,效率低
LinkedList
优点: 底层数据结构是链表,查询慢,增删快。
缺点: 线程不安全,效率高

  • 线程安全:都是不同步的,所有都是线程不安全的;
  • 底层数据结构
    • ArrayList:数组。因此,支持高效的随机访问,且随机访问的时间复杂度为 O(1)。但是插入和删除的时间复杂度为 O(n)。
    • LinkedList:双向链表数据结构 (JDK1.6 之前为循环链表,JDK1.7 取消了循环,注意双向链表和双向循环列表的区别)。因此,插入和删除的时间复杂度为 O(1)。随机访问的时间复杂度为 O(n)。
  • 内存占用空间:ArrayList 主要体现在 list 列表的结尾会预留一定的容量空间,而 LinkedList 的空间花费主要体现在它的每一个元素都有节点,会占用空间。

Set:存储的数据不能重复,无序的

Set有三个比较常用的类是散列集HashSet、链式散列集LinkedHashSet和树形集TreeSet

HashSet
底层数据结构是哈希表。(无序,唯一)
如何来保证元素唯一性?
1.依赖两个方法:hashCode()和equals()

LinkedHashSet
底层数据结构是链表和哈希表。(FIFO插入有序,唯一)
1.由链表保证元素有序
2.由哈希表保证元素唯一

TreeSet
底层数据结构是红黑树。(唯一,有序)

      1. 如何保证元素排序的呢?
        自然排序
        比较器排序
        2.如何保证元素唯一性的呢?
        根据比较的返回值是否是0来决定

Map

存储键值对映射;常用的有三个子类:HashMap、LinkedHashMap以及TreeMap   ||  Hashtable是线程安全的,HashMap不是线程安全的。

HashMap实现原理:是基于哈希表实现的,是一个“链表散列”的数据结构,即数组和链表的结合体。

hashmap实际上是一个数组+链表的数据结构,hashmap底层是一个数组结构,数组中每一项又是一个链表结构。链表是为了解决hash冲突。

inkedHashMap:LinkedHashMap是HashMap的子类,实现结构和HashMap类似,只是HashMap中的链表是单向链表,而LinkedHashMap是双向链表,只是在在HashMap的基础上加上了排序实现。

TreeMap底层采用打的红黑树算法;

 

IO流(Input   Output)

Java提供了io的四大抽象基类:

字节流:InputStream   OutputStream

字符流:Reader     Writer

文件流:FileInputStream   FileOutputStream

      FileReader   FileWriter

缓冲流:BufferedInputStream   BufferedOutputStream

                BufferedReader   BufferedWriter

转换流:当程序与文件的编码不一致时,使用转换流

        InputStreamReader   OutputStreamWriter

对象流(序列化流):ObjectInputStream  ObjectOutputStream

对于自定义对象如果想序列化,必须实现Serializable接口,并指定序列号:

如果自定义对象中有不需要序列化的属性时,使用transient(瞬态)关键字进行修饰。

打印流:PrintStream 将程序中需要打印的信息打印到文件中。(生成日志文件)

多线程:

线程概念:几乎所有的操作系统都支持同时运行多个任务,一个任务通常就是一个程序,每个运行中的程序就是一个进程。当一个程序运行时,内部可能包含了多个顺序执行流,每个顺序执行流就是一个线程。

 

并发与并行:

并发:同一时刻只能有一条指令执行,但多个进程指令被快速轮换执行

并行:同一时刻,有多条指令在多个处理器上同时执行 

 

现场的实现三种方式:

(1)、继承Thread类:

第一步:定义Thread类的之类,并重写run方法,该run方法的方法体就代表了线程需要执行的任务

第二步:创建Thread类的实例

第三步:调用线程的start()方法来启动线程

public class FirstThread extends Thread {
     
    private int i;
    public void run() {
        for(;i<100;i++) {
            System.out.println(getName()+" "+i);
        }
    }
     
    public static void main(String[] args) {
        for(int i=0;i<100;i++) {
            //调用Thread的currentThread方法获取当前线程
            System.out.println(Thread.currentThread().getName()+" "+i);
            if(i==20) {
                new FirstThread().start();
                new FirstThread().start();
            }
        }
         
    }
 
}

 

(2)、实现Runnable接口:

第一步:定义Runnable接口的实现类,并重写该接口的run方法,该run方法同样是线程需要执行的任务

第二步:创建Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象

ublic class SecondThread implements Runnable {
     
    private int i;
 
    @Override
    public void run() {
        for(;i<100;i++) {
            System.out.println(Thread.currentThread().getName()+" "+i);
        }
    }
     
    public static void main(String[] args) {
        for(int i=0;i<100;i++) {
            System.out.println(Thread.currentThread().getName()+" "+i);
            if(i==20) {
                SecondThread s1=new SecondThread();
                new Thread(s1,"新线程1").start();;
                new Thread(s1,"新线程2").start();
            }
        }
    }
     
}

(3)、使用Callable和Future创建线程

细心的读者会发现,上面创建线程的两种方法。继承Thread和实现Runnable接口中的run都是没有返回值的。于是从Java5开始,Java提供了Callable接口,该接口是Runnable接口的增强版。Callable接口提供了一个call()方法可以作为线程执行体,但call()方法比run()方法功能更强大。

创建并启动有返回值的线程的步骤如下:

第一步:创建 Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,且该call()方法有返回值,再创建 Callable实现类的实例。从Java8开始,可以直接使用 Lambda表达式创建 Callable对象

第二步:使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call方法的返回值

第三步:使用FutureTask对象作为Thread对象的target创建并启动新线程

第四步:通过FutureTask的get()方法获得子线程执行结束后的返回值

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
 
public class ThirdThread {
     
    public static void main(String[] args) {
        //ThirdThread rt=new ThirdThread();
        FutureTask<Integer> task=new FutureTask<Integer>((Callable<Integer>)()->{
            int i=0;
            for(;i<100;i++) {
                System.out.println(Thread.currentThread().getName()+"的循环变量i"+i);
            }
            return i;
        }) ;
         
        for(int i=0;i<100;i++) {
            System.out.println(Thread.currentThread().getName()+"的循环变量i为"+i);
            if(i==20) {
                new Thread(task,"有返回值的线程").start();;
            }
        }
        try {
            System.out.println("子线程的返回值"+task.get());
        }catch(Exception e) {
            e.printStackTrace();
        }
    }
 
}

 

采用Runnable、Callable接口的方式创建多线程的优缺点:

优点:

1、线程类只是实现了 Runnable接口或 Callable接口,还可以继承其他类

2、在这种方式下,多个线程可以共享同一个 target对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU、代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。

缺点:

编程稍稍复杂,如果需要访问当前线程,则必须使用Thread.currentThread()方法。

 

采用继承 Thread类的方式创建多线程的优缺点:

优点:

编写简单,如果需要访问当前线程,则无须使用 Thread.current Thread()方法,直接使用this即可获得当前线程

缺点:

因为线程已经继承了Thread类,所以不能再继承其他类

 

 

 

线程池:

创建线程池的几个常用的方法:

1.newSingleThreadExecutor
创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。

2.newFixedThreadPool
创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。

3.newCachedThreadPool
创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,

那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。

4.newScheduledThreadPool
创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
public class ThreadPoolTest {
     
    public static void main(String[] args) {
        ExecutorService pool=Executors.newFixedThreadPool(6);
        Runnable target=()->{
            for(int i=0;i<10;i++) {
                System.out.println(Thread.currentThread().getName()+"的i的值"+i);
            }
        };
        pool.submit(target);
        pool.submit(target);
        pool.submit(target);
        //关闭线程池
        pool.shutdown();
         
    }
 
}

线程安全问题:

为了解决线程问题,Java的多线程支持引入了同步监视器来解决这个问题,使用同步监视器的通用方法就是同步代码块。同步代码块的语法格式如下:

 synchronized(obj){

  //此处的代码就是同步代码块

}

与同步代码块对应,Java的多线程安全支持还提供了同步方法,同步方法就是使用 synchronized关键字来修饰某个方法,则该方法称为同步方法。对于 synchronized修饰的实例方法(非 static方法)而言,无须显式指定同步监视器,同步方法的同步监视器是this,也就是调用该方法的对象。同步方法语法格式如下:

public synchronized void 方法名(){

  //具体代码

}

从Java5开始,Java提供了一种功能更强大的线程同步机制—一通过显式定义同步锁对象来实现同步,在这种机制下,同步锁由Lock对象充当。

Lock提供了比 synchronized方法和 synchronized代码块更广泛的锁定操作,Lock允许实现更灵活的结构,可以具有差别很大的属性,并且支持多个相关的 Condition对象。

在实现线程安全的控制中,比较常用的是 ReentrantLock(可重入锁)。使用该Lock对象可以显式加锁、释放锁,通常使用ReentrantLock的代码格式如下:

class X{
    //定义锁对象
    private final ReentrantLock lock=new ReentrantLock();
    //...
     
    //定义需要保护线程安全的方法
    public void m() {
        //加锁
        lock.lock();
        try {
            //需要保证线程安全的代码
            //...method body
        }finally {
            //释放锁
            lock.unlock();
        }
    }
     

反射

获取字节码对象(Class对象)并操作。

获取字节码对象的三种方式:

    1. 根据对象创建:getClass()
    2. 使用类名.class获取
    3. 使用Class.forName(“类路径”) ,使用类路径获取

获取构造器、获取属性、获取方法

 

网络编程

七层网络模型:应用层、表示层、会话层、网络层、传输层、数据链路层、物理层。

TCP协议将网络模型划分为四层:应用层、传输层、网络层、链路层。

IP:指的是网络中的一台机器

端口号:指的是机器中的某一款应用程序

 

UDP:面向无连接,将传输的数据进行打包,大小不超过64KB

不太安全、会丢包

DatagramPacket(打包、拆包)   DatagramSocket(发包、收包)

 

TCP:提供了两个概念:客户端、服务器端。

Socket    ServerSocket

 

JDBC:JDBC中的核心类有:DriverManager、Connection、Statement,和ResultSet!

 

JDBC核心类(接口)介绍

DriverManger(驱动管理器)的作用有两个:

  l  注册驱动:这可以让JDBC知道要使用的是哪个驱动;

  l  获取Connection:如果可以获取到Connection,那么说明已经与数据库连接上了。

Connection对象表示连接,与数据库的通讯都是通过这个对象展开的:

  l  Connection最为重要的一个方法就是用来获取Statement对象;

  l  Statement是用来向数据库发送SQL语句的,这样数据库就会执行发送过来的SQL语句

  l  void executeUpdate(String sql):执行更新操作(insert、update、delete等);

  l  ResultSet executeQuery(String sql):执行查询操作,数据库在执行查询后会把查询结果,查询结果就是ResultSet;

ResultSet对象表示查询结果集,只有在执行查询操作后才会有结果集的产生。结果集是一个二维的表格,有行有列。操作结果集要学习移动ResultSet内部的“行光标”,以及获取当前行上的每一列上的数据:

  l  boolean next():使“行光标”移动到下一行,并返回移动后的行是否存在;

  l  XXX getXXX(int col):获取当前行指定列上的值,参数就是列数,列数从1开始,而不是0。

 

  

 1     @Test
 2     public void testConnection1() {
 3         try {
 4             //1.提供java.sql.Driver接口实现类的对象
 5             Driver driver = null;
 6             driver = new com.mysql.jdbc.Driver();
 7 
 8             //2.提供url,指明具体操作的数据
 9             String url = "jdbc:mysql://localhost:3306/test";
10 
11             //3.提供Properties的对象,指明用户名和密码
12             Properties info = new Properties();
13             info.setProperty("user", "root");
14             info.setProperty("password", "abc123");
15 
16             //4.调用driver的connect(),获取连接
17             Connection conn = driver.connect(url, info);
18             System.out.println(conn);
19         //最后一定要关闭
20         。。。。。。
21 
22         } catch (SQLException e) {
23             e.printStackTrace();
24         }
25     }

 

 

  GUI:

  1、GUI的概念

    GUI(Graphical User Interface)即图形用户界面,它能够使应用程序看上去更加友好。

  2、AWT、Swing以及SWT

    AWT(Abstract Windows Toolkit)是Java语言中最原始的GUI工具包,相关API位于java.awt包中。AWT是一个非常有限的GUI工具包,比如树、表格等都不支持;

    然而AWT却无法实现。AWT运行时,每个组件都要依赖于当前平台的GUI对等体(peer)控件,因此,AWT GUI 的外观和行为就会依赖当前平台。

  3、java.awt包

    java.awt包是Java内置的包,属于Java基础类库(JFC)的一部分,其中包括以下内容;

    便于用户输入的一组丰富的界面组件;

    将组件放置在适当位置的几种布局管理器;

    事件处理模型;

    图形和图像工具等等。

  4、常用的基本Swing组件

    在Swing编程中,有一些经常要使用到的组件,其中包括:

    JFrame(窗体,框架)、JPanel(面板,容器)、JButton(按钮)、JLabel(标签)、JTextField(文本框)、JTextArea(文本域)。

  5、创建GUI的步骤总结

    分析GUI中需要使用的组件;

    将GUI分成几个部分,每个部分使用JPanel布局。每个JPanel可以根据情况使用不同的布局管理器;

    将多个JPanel布局到一个JFrame上。

二、Swing事件监听快速入门

  1、事件处理

    对于采用了图形用户界面的程序来说,事件控制是非常重要的;

    到目前为止,我们编写的图形用户界面程序都仅仅只是完成了界面,而没有任何实际的功能,要实现相应的功能,必须进行事件处理;

    用户与GUI组件进行交互就会发生事件,如:按下一个按钮、用键盘输入一个字符、点击鼠标等等;

    当前我们要关注的并不是“事件是如何产生的”,而是讨论当发生事件后,我们应当“如何处理之”。

  2、事件处理模型

    Java中,事件处理的基本思路如下:

    一个源(事件源)产生一个事件(事件对象)并把它送到监听器那里,监听器只是简单地等待,直到它收到一个事件,一旦事件被接受,监听器将处理这些事件;

    一个事件源必须注册监听器以便监听器可以接受关于一个特定事件的通知。

  3、事件源与事件

    当在一个图形用户界面点击鼠标或者按下键盘时,都是针对于具体组件而发生的动作,如:使用鼠标点击某个按钮;按下键盘向文本框输入内容等等;

    我们把动作所操纵的对象称为事件源,请注意:事件源一定是指某个组件;

    当针对于事件源发生动作时,就会产生一个事件。

  4、监听器与监听器接口

    针对每一类型的事件,都有与之相对应的监听器,用于监听事件的发生;

    在Java中,监听器由一系列接口来提供;

    实际上,事件监听器就是实现了事件监听接口的类,监听器不断监听事件源的动作,当事件源产生一个事件后,监听器接收到事件源的通知,就调用特定的方法,以执行指定的动作;

    特定的事件监听器只对特定的事件感兴趣。

  5、事件类型

    实际上,事件是区分类型的,如:操作鼠标时会产生鼠标事件,使用键盘输入字符时会产生键盘事件,窗体打开或关闭时会产生窗体事件等等;

    对于不同类型的事件会有不同类型的监听器与之对应;

    java.awt.event包中包含了一系列监听器接口,分别用来处理不同类型的事件。

  6、事件对象

    Java中的所有事件都被封装在事件对象中,所有事件对象皆派生自EventObject类;

    对于不同的事件类型会有不同的事件对象,它们都以类似于XxxEvent的方式命名,如:ActionEvent、MouseEvent等等;

    事件对象中包含有事件发生时的相关信息(即事件触发时产生的一些数据),会被事件底层机制传递到事件处理函数中;

    实际上事件对象就是事件处理函数中被传递进来的参数,如果在处理事件的过程中需要使用到相关的某些数据,可以从事件对象中获取。

 

扩展:

 

 

 

 

posted on 2020-07-22 20:19  白嫖老郭  阅读(308)  评论(0编辑  收藏  举报

导航