1.jdk下载与环境变量配置

  • 下载官网:(https://www.oracle.com/index.html)
  • 配置:变量名为JAVA_HOME, 变量值为安装路径如:E:\javahome\, path值:%JAVA_HOME%bin
  • win+R, 输入cmd, 回车,再输入javac -version回车查看版本,再输入 java -version 若都成功则配置安装成功。

2.基本数据类型(四型八种)

  • byte by = 123;//一个字节,八位
  • short sh = 456;//短整型,两个字节,16位
  • int i = 12332;//整型, 四个字节,32位
  • long lon = 23142342131L;//长整型,八个字节,64位
  • float fo = 175.9F;//单精度浮点型,四个字节,32位,
  • 声明一个float类型变量,一个普通的小数默认是double类型
                必须在常数的后面加上f或F
    
  • double dou = 123.87;//双精度浮点型,八个字节,64位
  • boolean passed = false;//boolean类型,jvm中规定,计算机底层使用int类型存储Boolean类型,所以4字节
  • //字符类型变量char,可以和int整型数据类型相互转换但是不能超过最大值,\表示转义字符
    `cha`r ch1 = '男';`
    `int a = 66;`
    `System.out.println("ch1对应的整型是:" + (int)ch1);//强制类型转换`
    System.out.println("a对应的字符型是:" + (char)a);//强制类型转换`
    
  • /强制类型转换,从高精度向低精度转换/(需要的低数据类型)高精度数据类型例如:float f = (float)1212.121d;

3.短路与和短路或

  • boolean bool = n1 > n2 && ++n1 > n3, 如果n1>n2为flase,则后面部分则不会被执行,称为短路与。
  • boolean bool2 = n1 > n2 || —n1 >n3, 如果n1>n2为真,则后面不会被执行,称为短路或。
  • 按位与&和按位或|:6661. 按位与和逻辑与相似,但不会出现短路现象,按位或亦是如此。
  • 按位非~类似!

4.移位运算符

  • 左移位,表示3向左移位2位, 左移位运算<< 左移一位相当于乘2,左移两位相当于乘2的2次方。

    3 <<2(3为int型)

      1)把3转换为二进制数字0000 0000 0000 0000 0000 0000 0000 0011,

      2)把该数字高位(左侧)的两个零移出,其他的数字都朝左平移2位,

      3)在低位(右侧)的两个空位补零。则得到的最终结果是0000 0000 0000 0000 0000 0000 0000 1100,转换为十进制是12。

  • 向左移动32位,结果和输入的数一样 原因:32%32==0,移动0位 如果向左移动33位,33%32==1,移动1位 结果:输入24,得到24 * 2^1 =48

  • 右移位运算>>,右移一位相当于除2,右移n位相当于除2的n次方。无符号向右侧移动>>>,对负数有效变为正数,对整数和>>一样

5.循环

  • while循环:当条件为true时,可使用break;关键字跳出循环。continue;关键字表示结束本次循环,继续下一次循环。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    /*
    * 计算出100以内所有偶数的和,偶数的和,并比较大小,输出
    */
    int a = 1;
    int odd_number_sum = 0;//奇数和
    int even_number_sum = 0;//偶数和
    while (a < 101) {
    if (a % 2 == 0) {//判断为偶数
    even_number_sum += a;
    } else {
    odd_number_sum += a;
    }
    a++;
    }
  • do while循环:至少执行一次

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    /*生成随机数,用户输入0~5的数,猜数字游戏,do while循环至少执行一次 */
    Scanner scanner = new Scanner(System.in);
    //生成一个随机数
    Random random = new Random();//new一个生成随机数的对象
    int randomNumber;
    int number;
    do {
    System.out.println("请输入一个范围在0~5的整数:");
    number = scanner.nextInt();
    randomNumber = random.nextInt(5);//随机生成一个小于5的整数
    if (number == randomNumber) {
    System.out.println("恭喜你猜对了,随机数是" + randomNumber);
    } else {
    System.out.println("对不起,你猜错了,随机数是" + randomNumber);
    }
    } while (randomNumber != number);
  • for循环:

    1
    2
    3
    4
    5
    6
    7
     //打印九九乘法表
    for (int i = 1; i <= 9; i++) {//外层循环控制换行
    for (int j = 1; j <= i; j++) {//内层循环输出
    System.out.print(j+ " x " + i + " = " + (i * j) + " ");
    }
    System.out.println();//换行
    }
  • for循环迭代:

    1
    2
    3
    4
    5
    //for循环迭代
    int[] nums = {12, 34, 567, 34, 1324, 12};//数组
    for (int i : nums) {
    System.out.print(i + " ");
    }

6.冒泡排序

1、比较相邻的元素。如果第一个比第二个大,就交换他们两个。

2、对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。

3、针对所有的元素重复以上的步骤,除了最后一个。

4、持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//冒泡排序
int temp;//临时变量
for (int i = 0; i < scores.length - 1; i++) {//外层循环控制总的排序次数
/*内层循环实现排序*/
for (int j = 0; j < scores.length - 1 - i; j++) {
/*对相邻两个数进行判断*/
if (scores[j] < scores[j + 1]) {
temp = scores[j];
scores[j] = scores[j + 1];
scores[j + 1] = temp;//依次比较将最小数置于末尾
}
}
}
/*使用冒泡排序递增排序*/
for (int i = 0; i < scores.length - 1; i++) {
for (int j = 0; j < scores.length - 1 - i; j++) {
if (scores[j + 1] < scores[j]) {
temp = scores[j + 1];
scores[j + 1] = scores[j];
scores[j] = temp;
}
}
}

7.数组

  • 一维数组:String[] names = {"小米", "小明", "莱昂纳多"};静态方式创建数组 ,数组在JVM中采用栈和堆的储存方式,通过names在栈中地址访问堆(里面为数据) int[] nums = new int[5];//指定数组长度

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int[] nums = {56, 28, 15, 999, 30, 65, 12, 77};
    int temp;//临时变量
    for (int i = 0; i < nums.length / 2; i++) {
    temp = nums[i];
    nums[i] = nums[nums.length - (i + 1)];
    nums[nums.length - (i + 1)] = temp;
    }
    for (int num : nums) {
    System.out.print(num + "\t");
    }
  • 二维数组:int[][] stuScores;//声明二维数组变量

    1
    `  stuScores = new int[3][3];//创建一个二维数组`

8.面向对象

  • java对象在JVM中储存:Person person;//声明一个自定义类型的局部变量,存储在JVM的栈中, 使用构造方法创建一个Person类型的对象;赋值给person变量, 对象存储在JVM的堆中;只有new才会在内存堆中新建一个对象 person = new Person();

  • 访问修饰符:

    1. public:公共的,最大访问级别。
    2. protected:保护的,不同包中只有子类允许访问。
    3. 缺省:默认的,不同包中不允许访问。
    4. private:私有的,只允许在本类中访问。
  • 构造方法:

    1. 方法名称和类名完全相同,没有任何返回类型,这样的方法是构造方法(构造器)

    2. 构造方法是用来创建对象使用的,使用new 运算符调用并创建一个对象

    3. 带参数的构造器目的就是为对象进行成员属性初始化

      1
      2
      3
      4
      5
      6
      /*局部变量和成员实例属性重合时可以使用this关键字指向成员变量*/
      public Employee(String name, int workAge) {
      this.name = name;
      this.workAge = workAge;
      System.out.println(name + " " + workAge);
      }
    4. 如果构造器被定义多个称为构造方法重载构造器重载,自定义有参构造器将会覆盖系统默认提供的无参构造器,如果需要使用则必须重新显示定义。

9.继承,多态,接口

  • 继承:继承是类与类之间的关系,非对象与对象之间的关系,使用关键字extend, 创建子类对象时总是要先创建一个父类对象,默认子类的构造方法总是自动调用父类的无参构造方法 .
  • java的三大特性:封装、继承、多态(方法重载、方法重写)。
  • final关键字修饰的类不能被继承,构造方法不能被继承,final修饰的类不能被继承,不能被重写。
  • 方法重载是在同一个类中,方法重写出现在子类当中
  • super关键字,不能出现在静态方法中,super关键字在子类的构造方法中代表父类的构造器。
  • 抽象类:
    1. Java核心编程思想是面向对象,面向对象核心编程思想是面向抽象。
    2. 不能使用final关键字修饰。
    3. 自身不能够实例化。
    4. 用来被继承。
  • 适配器: 适配器(Adaptor)创建一个普通类作为适配器类,继承抽象类,实现所有抽象类方法,在用非抽象子类继承适配器,选择性重写抽象方法。
  • 接口:接口中属性定义必须是公共的,静态的常量;接口中只允许定义公共的抽象的实例方法。接口中所有对象都是上转型对象。

10.静态代码块

  • 允许访问静态属性,调用静态方法,定义局部变量及常量,定义局部类。

  • 不允许访问实例属性和方法以及定义方法。

  • 静态代码块属于类,和对象无关,随类的加载而加载。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*定义静态的常量*/
private static final String DRIVER;
private static final String URL;
private static final String USER;
private static final String PASSWORD;
/*静态块
* 可以访问静态常量,静态变量,静态方法
* 定义静态内部类
* */
static {
//给常量赋值
DRIVER = "com.mysql.jdbc.Driver";
URL = "jdbc:mysql://localhost:3306/java";
USER = "root";
PASSWORD = "123456";
}

11.常用库介绍

  • Object类:

    1. 是所有类的超级父类,java任何引用类型对象都可以赋值给Object类型变量。
    2. Object类提供的常用方法:toString()方法;equals方法用来判定给定对象是否与当前对象相等;getClass方法返回当前对象的运行时类(Class)对象,此方法不允许子类进行重写:public final Class getClass();
  • Character包装类:

    1. Character.isDigit(chars[i])判断是否为数字
    2. Character.isLetter(chars[i])判断是否为字母
    3. Character.isLowerCase(chars[i])判断是否为小写字母
    4. Character.isUpperCase(chars[i])判断是否为大写字母
    5. Character.toUpperCase(chars[i]);字母转换为大写字母
    6. Character.toLowerCase(chars[i]);字母转换为小写字母
  • Integer:

    1
    String strNumber = Integer.toString(number);//将整型转换为字符串
    1
    Integer.parseInt(String.valueOf(chars[i]));//将字符转换为字符串再转换整型

12.String字符串以及常用方法

  • String str=”IU”;字符串常量不可以被更改只能被覆盖;存储在jvm堆中的静态常量区.
  • toCharArray();此方法返回char型数组.
  • contains(" ")判断是否包含空格
  • length();返回字符串长度
  • String str3 = new String(chars, 3, 8);//aChinese,3:表示索引,8:索引开始取几个
  • 比较两个字符串是否相等,equals比较的是字符串的序列化值是否相等,==比较值和是否是同一个对象
  • 通过索引查找字符:charAt(index);
  • 判断结尾和开始:startsWith("我爱中国"),endsWith("qq.com");
  • 去掉字符串前后的空格:str.trim();
  • 查找字符串中指定字符索引:
    1. email.indexOf('@')返回字符索引值
    2. email.indexOf(".com")返回字符串索引
    3. email.indexOf('9',0)从指定索引查找
  • str.split(tag);//返回一个字符串数组
  • 提取字串:
    1. substring(3);从索引位置开始提取
    2. substring(3, 12);//3:开索引始,12:索引结束(最后不取该值)
  • toLowerCase();转换为小写
  • toUpperCase();转换为大写
  • replace("小", "大");//将小替换为大
  • StringBuffer:StringBuffer buffer = new StringBuffer("^_^ ")

    1. StringBuffer是线上安全,线程同步的
    2. buffer.append("qwq")连接字符串
  • StringBuilder:StringBuilder stringBuilder = new StringBuilder(base);//构建可变字符串

    1. stringBuilder.toString();//返回连接的字符串
    2. 非线程同步,不涉及多线程使用比StringBuffer效率更高

13.日期和时间类

  1. SimpleDateFormat实现对Date的字符串格式化,是DateFormat的子类
1
2
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String birthday = sdf.format(this.birthday);//对日期对象进行格式化

Calendar对象的创建和使用(抽象类,不能实例化对象)日历

Calendar cal = Calendar.getInstance();//使用默认时区并指向当前系统时间创建一个日历实例

1
2
3
4
/*获取年月日*/
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH) + 1;//月份从0开始到11,所以要加1
int date = cal.get(Calendar.DATE);

Date currentDate = cal.getTime();获取当前日历对象所对应的date对象

1
2
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String strCurrentDate = sdf.format(currentDate);

set(int year,int month, int date);设置日历的年份,月份,日期值

14.Math类

  • 所有属性和方法都为static的,不需要创建实例,final修饰的终极类不能被继承
  • Math.abs(-12)计算绝对值
  • Math.cbrt(27.0)计算立方根
  • Math.max(a,b),Math.min(a,b)比较大小
  • Math.pow(x,y)计算x的y次方
  • Math.random()返回0.0到1.0的随机数

15.集合

  1. Map接口(HashMap不是现程安全的。HashTable是线程同步的)

    1
    2
    3
    Map<String, Object> carMap = new HashMap<>(); /*存储键值对在哈希表*/        carMap.put("key0", car0);        
    carMap.put("key2", car2);
    carMap.put("key3", car3);

    carMap.get("key0")通过键取值

    /*获取所有键的集合*/ Set keySet = carMap.keySet();不重复

    /*取出哈希表中所有的值的集合*/ Collection coll = carMap.values();

    carMap.containsKey("key0")判断是否包含给定键

  2. List集合

    1. List<User> userList = new ArrayList<>();//创建List集合对象
    2. userList.contains(new User())//判断集合中是否包含给定对象
    3. userList.clear();清空集合元素
    4. :list中根据索引将元素数值改变(替换)注意 .set(index, element); 和 .add(index, element)
  3. Vector集合实现类:向量集合,适用场景在处理多线程应用中

    Vector<User> vector = new Vector<>();//创建集合向量

    "当前集合是否为空:" + vector.isEmpty()

    当前集合元素个数:" + vector.size())

    vector.remove(user3);//删除元素

    1
    2
    3
    4
    5
    /*获取Vector独有的新方法提供元素枚举迭代器*/       
    Enumeration enu = vector.elements();
    while (enu.hasMoreElements()) {
    User user = (User) enu.nextElement();//将Object类型强制转换 System.out.println(user);
    }
  4. Set接口:没有索引,不能存储重复数据,会覆盖。(对象不能一样)

    1. Set<Product> set = new HashSet<Product>(16);//指定初始容量,默认是16,会自动扩容
  5. TreeSet类接口,排序,效率比HashSet要低

    1. TreeSet类接口,排序

16.异常

  • Throwable是所有异常的父类,Error错误重启java虚拟机才行,Exception异常修改代码可解决。
  • 使用throws关键字声明异常,多个异常逗号隔开;使用throw关键字满足条件时抛出异常
1
2
3
4
5
6
7
8
9
10
11
12
13
14
try {//捕获异常 

} catch (SQLException | IOException e) {//处理异常
String errorMessage = e.getMessage();//获取异常信息
System.err.println(errorMessage);
System.out.println(e.getClass().getName());
e.printStackTrace();
} finally {//强制执行块,用于释放被占用的资源
try { if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}

17.File

常用构造方法:

  1. File(File dir,String child)
  2. File(String pathName)
  3. File(String parent,String child)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
File resFile = new File("f:\\file\\java.data")
/*判断file对象是否在硬盘上存在*/
/*createNewFile方法必须确保被创建的文件的父目录都存在,否则出现IOException
* 系统找不到指定的路径。
* */
if (resFile.exists()) {
System.out.println("文件是可读的吗?" + resFile.canRead());
System.out.println("文件是可写入的嘛?" + resFile.canWrite());

System.out.println("文件绝对路径:" +
resFile.getAbsolutePath());//f:\file\java.data
System.out.println("基本路径:" + resFile.getPath());//f:\file\java.data
System.out.println("父路径:" + resFile.getParent());//f:\file
System.out.println("文件名称:" + resFile.getName());//java.data
/*判断文件是目录还是具体文件*/
System.out.println("文件是目录嘛?" + resFile.isDirectory());//false
System.out.println("具体文件:" + resFile.isFile());//true
// System.out.println(resFile.delete());//删除文件

18.输入流(InputStream对目标文件进行读取操作)

  • 读取二进制文件,字节输入流:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    /*建立目标要读取的文件对象*/
    File file = new File(filePath);
    /*基于目标文件建立输入流*/
    InputStream in = null;
    if (file.exists()) {//如果文件存在,创建文件输入流
    try {
    in = new FileInputStream(file);//使用子类FileInputStream创建二进制输入流
    int count = 0;//读取到的字节数
    byte[] bytes = new byte[124];//临时存储读取到的二进制文件
    /*将读取到的字节数存储到bytes字节中,每次从索引开始存储,存储的长度是
    bytes.length,覆盖*/
    while ((count = in.read(bytes, 0, bytes.length)) != -1) {//循环处理读取,读到文件末尾count为-1
    String s = new String(bytes, 0, count);//索引0开始,读取长度count
    System.out.println(s);
    }

    } catch (IOException e) {
    e.printStackTrace();
    } finally {
    try {
    if (in != null) {
    in.close();//关闭流,释放资源
    System.out.println("关闭成功");
    }
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }

  • 字符输入流:读取文本文件不会出现乱码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    FileReader fileReader = null;
    if (file.exists()) {
    try {
    fileReader = new FileReader(file);
    int count = 0;
    char[] chars = new char[30];
    while ((count = fileReader.read(chars, 0, chars.length)) != -1) {
    String s = new String(chars, 0, count);
    System.out.print(s);
    }
    } catch (IOException e) {
    e.printStackTrace();
    }finally {
    try {
    if (fileReader != null) {
    fileReader.close();//关闭流,释放资源
    System.out.println("关闭成功");
    }
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
  • 使用BufferedReader缓冲流:提高效率(字符输入流)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    FileReader fileReader = null;//基于文件的普通输入流
    BufferedReader br = null;//基于某个Reader建立的字符缓冲流(处理流)
    if (file.exists()) {
    try {
    fileReader = new FileReader(file);//基于文件建立普通文本输入流
    br = new BufferedReader(fileReader);//基于某个Reader建立文本缓冲流
    int count = 0;
    char[] chars = new char[25];
    while ((count = br.read(chars, 0, chars.length)) != -1) {
    String s = new String(chars, 0, count);
    System.out.print(s);
    }
    } catch (IOException e) {
    e.printStackTrace();
    } finally {
    try {
    br.close();
    fileReader.close();
    } catch (IOException e) {
    e.printStackTrace();
    }

    }
    }

19.输出流(OutputStream对目标文件进行写入操作)

  • 二进制输出流

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public static void binaryOutputStream(File file) {
    String str = "start=D:\\java课程\\第十九天\\unit12 二级制输出流一(153).mp4";
    byte[] bytes = str.getBytes();//将字符串转换为字节数组
    OutputStream out = null;
    try {
    out = new FileOutputStream(file);
    out.write(bytes);//调用write方法将字节数组的数据写入目标文件file
    } catch (IOException e) {
    e.printStackTrace();
    } finally {
    if (out != null) {
    try {
    out.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    }
  • 数据比较大时使用缓冲流:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public static void useBufferedOutputStream(File file) {
    OutputStream os = null;
    BufferedOutputStream bs = null;
    String str = "君不见高堂明镜悲白发,朝如青丝暮成雪。";
    byte[] bys = str.getBytes();
    if (file.exists()) {
    try {
    System.out.println(file.getAbsolutePath());
    os = new FileOutputStream(file.getAbsolutePath() + "/诗词.doc");
    bs = new BufferedOutputStream(os);//基于某个OutputStream建立缓冲输出流
    bs.write(bys, 0, bys.length);//写入目标文件
    } catch (IOException e) {
    e.printStackTrace();
    } finally {
    try {
    bs.close();
    os.close();
    } catch (IOException e) {
    e.printStackTrace();
    }

    }
    }
    }

20.文件的复制(流的对接)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public static void copeFile(File target, File dir) {
InputStream in = null;//文件输入流,读取文件
OutputStream os = null;//文件输出流,写入文件
File copyFile = null;
if (target.exists()) {//判断目标文件是否存在
if (!dir.exists()) {//如果目录不存在,创建目录
dir.mkdirs();
}
try {
in = new FileInputStream(target);//基于文件建立输入流
String fileName = target.getName();//获取目标文件名称
/*避免文件重名被覆盖,可以拍使用系统时间的毫秒作为文件前缀*/
copyFile = new File(dir + "/" + new Date().getTime() + fileName);
os = new FileOutputStream(copyFile, Boolean.parseBoolean("utf-8"));//基于目标文件建立输出流
byte[] bytes = new byte[1024];//临时存储字节数据缓冲区
int count = 0;//记录读取内容的长度
while ((count = in.read(bytes, 0, bytes.length)) != -1) {
//文件复制读取中......
System.out.println("文件复制读取中......");
os.write(bytes, 0, count);//将临时缓冲区的内容写入目标文件
}
System.out.println("文件复制完成");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
os.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

21.序列化读写

  • 序列化流,将一个java对象保存到目标文件(ObjectOutputStream)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public static void javaSerializableAction(Employee emp, File file) {
    OutputStream os = null;
    ObjectOutputStream oos = null;//序列化流
    if (emp != null) {
    try {
    os = new FileOutputStream(file);
    oos = new ObjectOutputStream(os);
    oos.writeObject(emp);//将序列化文件保存到目标文件
    } catch (IOException e) {
    e.printStackTrace();
    } finally {
    try {
    oos.close();
    os.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    }
  • 反序列化流,从目标文件读取序列化java对象到内存(ObjectInputStream)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public static Employee deserializableJavaObject(File file) {
    InputStream in = null;//创建输入流
    ObjectInputStream ois = null;
    Employee emp = null;
    if (file.exists()) {//如果文件存在
    try {
    in = new FileInputStream(file);
    ois = new ObjectInputStream(in);
    //进行反序列化(串行化)
    Object object = ois.readObject();
    emp = object != null ? (Employee) object : null;
    } catch (IOException | ClassNotFoundException e) {
    e.printStackTrace();
    }
    }
    return emp;
    }

22.多线程

  • Thread线程类

    1. 任何一个Thread实例调用start方法将启动运行一个线程
    2. Thread的run方法是线程启动后自动执行的业务方法
  • 线程的生命周期

    1. 第一阶段:新建状态(此时线程还没有运行)
    2. 第二阶段:运行状态(线程开始运行并自动执行run方法)
    3. 第三阶段:中断状态(多种原因使线程处于终止)
    4. 第四阶段:死亡状态(释放线程对象,不在回复运行)
  • Runnable线程接口:有利于实现多个线程之间的数据共享,多个Thread实例共享此接口的run方法

  • interrupt()方法:中断某个线程的状态

  • 线程之间的通信

    1. 同步代码块:被同步的代码块在一个线程对象进行访问时,其他线程是没有访问权限的,只有这个当前线程对象完全执行完了这个代码块,释放了同步锁,其它线程才可以访问这个代码块。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      public class Syncode implements Runnable {
      @Override
      public void run() {
      synchronized (this) {//那个类调用就是那个对象,com.znzz.multiThread.SynCode@8e6ae55
      Thread current = Thread.currentThread();//获取当前线程
      for (int i = 0; i < 5; i++) {
      System.out.println("当前执行同步代码块的线程名称是:" + current.getName());
      try {
      Thread.sleep(1000);
      } catch (InterruptedException e) {
      e.printStackTrace();
      }
      }
      }
      }
      }
    2. 对象同步锁:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      public class SynObject implements Runnable {
      private Dog dog;

      public SynObject() {
      if (dog == null) {
      dog = new Dog();
      }
      }

      @Override
      public void run() {
      synchronized (dog) {//对象同步锁
      Thread current = Thread.currentThread();//获取当前线程
      for (int i = 0; i < 5; i++) {
      System.out.println(current.getName() + "正在修改dog名字:");
      dog.setName("米卡" + i);
      System.out.println("名字被修改为" + dog.getName());
      try {
      Thread.sleep(1000);
      } catch (InterruptedException e) {
      e.printStackTrace();
      }
      }
      }
      }
      }
    3. 方法同步锁:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      public class SynMethod implements Runnable {
      private double money = 100000;

      @Override
      public void run() {
      doMoney();
      }
      private synchronized void doMoney() {
      Thread current = Thread.currentThread();
      for (int i = 1; i <= 5; i++) {
      if (current.getName().equals("会计")) {
      System.out.println(current.getName() + " 正在入账......");
      money *= i;
      System.out.println("账户:" + money);
      }
      if (current.getName().equals("出纳")) {
      System.out.println(current.getName() + " 正在分账......");
      money = money * i - 0.2 * money;
      System.out.println("账户:" + money);
      }

      try {
      Thread.sleep(1000);
      } catch (InterruptedException e) {
      e.printStackTrace();
      }
      }
      System.out.println("总帐:" + money);
      }
      }

23.网络编程

  • IP地址:IP 地址(Internet Protocol Address)是互联网协议特有的一种地址,它是 IP 协议提供的一种统一的地址格式。IP 地址为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。与域名绑定。
  • 端口号:ip地址是用来标志服务器的。但是一个服务器上会有很多个程序同时使用网络,那怎么保证他们的网络包不串线?好了,端口号就入场了,它是0-65535之间的一个数字。服务端是监听一个固定的端口,比如80,这样客户端在连接的时候都知道该连哪个应用。客户端是从未占用的里面随机挑选一个就可以(但一般不会选1024以下)。

24.枚举数据类型

  1. 枚举类用关键字enum修饰,用来定义不变的值,类似于final修饰的 常量;
  2. 枚举类中还可以定义方法,内部类,变量等,但都必须定义在枚举数据之后。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
枚举类型
* */
public enum SignalLamp {//交通信号灯
RED,
GREEN,
YELLOW;
/*后面定义其他类型及方法*/
private int num = 100;
static class InnerClass {

}
/*还可以定义接口*/
interface Dao {

}
}

25.反射编程

  • Java中的反射编程是通过JVM运行时获取某个类型的字节码(Class)对象,从而利用其反向获取此类型定义的内部信息实现编程的一种机制。

  • Class类:Class类的实例表示正在运行的Java应用程序中的类和接口,是字节码实例。

  • eg.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    public static void main(String[] args) {
    try {
    Class<?> stuClass = Class.forName("com.znzz.practice.Student");
    /*使用字节码对象获取关于这个类的对象实例*/
    Student student = (Student) stuClass.newInstance();//默认调用此类的无参构造实例化对象,返回对象是Object类型
    System.out.println(stuClass.getName());//com.znzz.practice.Student

    /*获取类的访问级别*/
    System.out.println(stuClass.getModifiers() == Modifier.PUBLIC);//true

    /*获取所有公共级别的字段*/
    Field[] fields = stuClass.getFields();
    for (Field f : fields) {
    System.out.println(f);//public java.lang.String com.znzz.practice.Student.name
    }

    System.out.println("所有访问级别的字段数组长度:" + stuClass.getDeclaredFields().length);//3

    /*获取类中定义的构造器*/
    Constructor con0 = stuClass.getConstructor(String.class, Integer.class);
    System.out.println(con0 != null);//true

    /*获取所有构造器*/
    Constructor[] constructors = stuClass.getConstructors();
    System.out.println(constructors.length);//3个构造器

    /*获取类中定义的方法*/
    Method[] methods = stuClass.getMethods();//获取所有公共访问级别的方法,获取所有方法用stuClass.getDeclaredMethods()
    System.out.println(methods.length);//11包括父类中的方法
    for (Method m : methods) {
    System.out.println(m.getName());
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
  • Constructor类:表示某个类的构造方法实例类型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public static void main(String[] args) {
    try {
    Class<?> stuClass = Class.forName("com.znzz.practice.Student");//获取字节码对象
    /*获取构造器*/
    Constructor cons = stuClass.getConstructor(String.class, Integer.class);//如果无参数就是无参构造器
    /*使用构造器反射方法实现对象的创建*/
    Student student = (Student) cons.newInstance("李知恩", 26);//返回Object类型,强制类型转换
    System.out.println(student.getName() + " " + student.getAge());

    System.out.println("构造器的参数个数是:" + cons.getParameterCount());//2
    System.out.println(cons.getModifiers() == Modifier.PUBLIC);//构造器的访问级别 true
    System.out.println(cons.getName());//com.znzz.practice.Student
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
  • Filed和Method类反射编程:Field提供有关类或接口的单个字段信息,以及对它的动态访问权限。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    public class TestFieldAndMethod {
    public static void main(String[] args) {
    try {
    Class<?> stuClass = Class.forName("com.znzz.practice.Student");//加载类
    Student student = (Student) stuClass.newInstance();//通过反射获取一个实例对象
    /*获取某个成员字段*/
    Field nameField = stuClass.getField("name");//获取公共级别的属性字段
    nameField.set(student, "lisa");//为公共字段赋值
    /*使用反射获取某个对象字段的属性值*/
    System.out.println(nameField.get(student));//lisa

    /*获取不可见的字段属性private*/
    Field ageField = stuClass.getDeclaredField("age");
    if (ageField.getModifiers() == Modifier.PRIVATE) {
    /*运行时动态改变私有字段的访问级别*/
    ageField.setAccessible(true);//访问级别设置为public
    ageField.set(student, 28);
    System.out.println(ageField.get(student));//28
    }

    Field sexField = stuClass.getDeclaredField("sex");
    if (!sexField.isAccessible()) {
    sexField.setAccessible(true);
    sexField.set(student, "女");
    System.out.println(sexField.get(student));
    }

    /*Method反射编程*/
    Book book = new Book();
    book.setName("《红楼梦》");
    Method method = stuClass.getMethod("learn", Book.class);//方法名,参数类型
    method.invoke(student, book);//执行方法

    /*获取非公共可见级别的方法*/
    Method method2 = stuClass.getDeclaredMethod("run");
    if (!method2.isAccessible()) {//如果访问级别不是公共可见的
    method2.setAccessible(true);//运行时更改此方法的访问级别
    method2.invoke(student);
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }