乐趣区

关于java:API专题

概述

所有能够调用的都是 API

目标

学习 java 里提供的各种工具类的应用(工具类提供的构造方法,一般办法,成员变量)

学习工具

api 手册

Object

概述

类 Object 是类层次结构的根类。每个类都应用 Object 作为超类。所有对象(包含数组)都实现这个类的办法。

罕用办法

 System.out.println(o.hashCode() );// 返回该对象的哈希码值。– 哈希码值了解为编号
 ​
 System.out.println(o.toString() );// 返回该对象的字符串示意
 ​
 System.out.println(o);// 对象在内存中的地址值
 ​
 System.out.println(o.equals(123) );// 批示其余某个对象是否与此对象“相等”。

总结

–toString– 默认应用的是 Object 的 toString()展现的是地址值,如果想要属性值就要进行重写

– 重写 equals– 默认应用的是 Object 的 equals()展现的是地址值之间的比拟,不想比拟地址值,想比拟属性值

– 主动生成 –generate….

instanceof java 里的关键字,通常用来判断 obj instanceof student obj 是不是学生类型。

string

概述

String 类代表字符串。Java 程序中的所有字符串字面值(如 “abc”)都作为此类的实例实现。

字符串是常量;它们的值在创立之后不能更改。字符串缓冲区反对可变的字符串。

罕用办法

 char charAt(int index)
 ​
 •     返回指定索引处的 char 值。
 ​
 • String concat(String str)
 ​
 •     将指定字符串连贯到此字符串的结尾。
 ​
 • boolean contains(CharSequence s)
 ​
 •     当且仅当此字符串蕴含指定的 char 值序列时,返回 true。
 ​
 • boolean endsWith(String suffix)
 ​
 •     测试此字符串是否以指定的后缀完结。
 ​
 • boolean equals(Object anObject)
 ​
 •     将此字符串与指定的对象比拟。
 ​
 • byte[] getBytes()
 ​
 • int hashCode()
 ​
 •     返回此字符串的哈希码。
 ​
 • int indexOf(String str)
 ​
 •     返回指定子字符串在此字符串中第一次呈现处的索引。
 ​
 boolean isEmpty()
 ​
 •     当且仅当 length() 为 0 时返回 true。
 ​
 • int length()
 ​
 •     返回此字符串的长度。
 ​
 • int lastIndexOf(String str)
 ​
 •     返回指定子字符串在此字符串中最左边呈现处的索引。
 ​
 String replace(char oldChar, char newChar)
 ​
 用新的代替旧的
 ​
 • String[] split(String regex)
 ​
 •     依据给定正则表达式的匹配拆分此字符串。
 ​
 • boolean startsWith(String prefix)
 ​
 •     测试此字符串是否以指定的前缀开始。
 ​
 • String substring(int beginIndex)
 ​
 •     返回一个新的字符串,它是此字符串的一个子字符串。
 ​
 • String substring(int beginIndex, int endIndex)
 ​
 •     返回一个新字符串,它是此字符串的一个子字符串。
 ​
 • char[] toCharArray()
 ​
 •     将此字符串转换为一个新的字符数组。
 ​
 • String toLowerCase()   全副转换为小写
 ​
 • String toUpperCase()   全副转换为大写
 ​
 String trim()
 ​
 •     返回字符串的正本,疏忽前导空白和尾部空白。
 ​
 • static String valueOf(int i)
 ​
 •     返回 int 参数的字符串示意模式。

StringBuilder/StringBuffer

概述

都是用来进行字符串拼接的优化计划

罕用办法

 StringBuilder append(string b)

包装类

概述

为了对应的根本类型提供丰盛的办法

根本类型 byte short int long float double char boolean

包装类型 Byte Short Integer Long Float Double Character Boolean

Number

– 提供将示意的数值转换为 byte、double、float、int、long 和 short 的办法。

integer

创建对象

Integer(int value)

罕用办法

 int intValue()
 ​
 •     以 int 类型返回该 Integer 的值。
 ​
 • static int parseInt(String s)
 ​
 •     将字符串参数作为有符号的十进制整数进行解析。
 ​
 • static Integer valueOf(int i)
 ​
 •     返回一个示意指定的 int 值的 Integer 实例。
 ​
 

日期类

概述

类 Date 示意特定的霎时,准确到毫秒

创建对象

Date()

罕用办法

  getXxx()
 ​
 System.out.println(d.getTime() );// 从 1970,1,1 零点到当初的毫秒值
 ​
 System.out.println(d.getClass() );// 返回此 Object 的运行时类 System.out.println(d.getDate() );// 获取明天是一个月里的第几天
 ​
 System.out.println(d.getHours() );// 获取当初是几点
 ​
 System.out.println(d.getDay() );// 明天星期几
 ​
 System.out.println(d.getMinutes() );// 获取一个小时里的第几分钟
 ​
 System.out.println(d.getMonth() + 1 );// 底层获取到天然月 -1,0~11 示意 12 个月
 ​
 System.out.println(d.getSeconds() );// 获取当初是哪一秒
 ​
 System.out.println(d.getYear() );// 获取从 1900 年到当初一共是多少年
 ​
 System.out.println(d.toLocaleString());//2020-9-15 14:40:03

日期工具 SimpleDateFormat

概述

把 String 类型的日期 和 Date 类型的日期 互转

创建对象

  SimpleDateFormat(String pattern)

罕用办法

  Date -> String : String format(Date date)
 ​
  String -> Date : Date parse(String text)

BigDecimal/BigInteger

概述

BigDecimal 专门用来解决 小数运算 不准确的问题

BigInteger 专门用来解决 超大的 整数运算

不可变的、任意精度的有符号十进制数。

BigDecimal 创建对象

BigDecimal(double val) – 构造方法有坑,会使计算更加不准确。

BigDecimal(String val)

罕用办法

加法运算: BigDecimal add(BigDecimal augend)

减法运算: BigDecimal subtract(BigDecimal subtrahend)

乘法运算: BigDecimal multiply(BigDecimal multiplicand)

除法运算: BigDecimal divide(BigDecimal divisor,要保留的小数位,舍入模式)四舍五入 BigDecimal.ROUND_HALF_UP

File 文件工具类

概述

文件和目录路径名的形象示意模式

创建对象

File(String pathname)

调用办法

 System.out.println(file.length() );// 获取文件的大小
 ​
 
 ​
 System.out.println(file.exists() );// 判断文件是否与存在
 ​
 
 ​
 System.out.println(file.isFile() );// 判断资源是文件吗
 ​
 
 ​
 System.out.println(file.isDirectory() );// 判断资源是文件夹吗
 ​
 
 ​
 System.out.println(file.getName() );// 获取文件名
 ​
 
 ​
 System.out.println(file.getAbsolutePath() );// 获取残缺门路
 ​
 
 ​
 
 ​
 System.out.println(file.getParent() );// 获取文件的父门路
 ​
 
 ​
 file = new File(“F:java2.txt”);
 ​
 System.out.println(file.createNewFile() );// 创立不存在的文件 2.txt
 ​
 
 ​
 file = new File(“F:javaabc”);
 ​
 System.out.println(file.mkdir() );// 创立不存在的文件夹 abc
 ​
 
 ​
 file = new File(“F:javamnx”);
 ​
 System.out.println(file.mkdirs() );// 创立不存在的多个文件夹 m n x
 ​
 
 ​
 file = new File(“F:java2.txt”);
 ​
 System.out.println(file.delete() );// 删除文件 或者 空的文件夹
 ​
 
 ​
 file = new File(“F:java”);
 ​
 String[] names = file.list() ;// 获取所有资源的 名字 存入 String[]
 ​
 System.out.println(Arrays.toString(names) );//[1.txt, abc, m]
 ​
 
 ​
 File[] fs = file.listFiles() ;// 获取所有资源 并封装成一个一个的 File 对象, 存入 File[]– 举荐!!
 ​
 System.out.println(Arrays.toString(fs) );
 ​
 
 ​
 //TODO 创立 3 个 File 对象并存入容器里(数组)
 ​
 File f1 = new File(“ 文件或者文件夹门路 1”);
 ​
 File f2 = new File(“ 文件或者文件夹门路 2”);
 ​
 File f3 = new File(“ 文件或者文件夹门路 3”);
 ​
 
 ​
 File[] a = new File[3];// 怎么决定数组的类型?– 看你要存的数据的 类型
 ​
 •   a[0] = f1;
 ​
 •   a[1] = f2;
 ​
 •   a[2] = f3;
 ​
 •   System.out.println(Arrays.toString(a) );
 ​
 

统计文件夹里 所有文件的大小

 1, 接管用户输出 文件夹门路
 ​
 String path = new Scanner(System.in).nextLine();
 ​
 File ff = new File(path);// 封装成 File 对象
 ​
 2, 列出 文件夹里 的所有资源, 并封装成一个一个的 File 对象, 放入 File[]
 ​
 •   File[] aa = ff.listFiles() ;
 ​
 •   long sum = 0 ;// 定义变量, 记录文件的总和
 ​
 •   // 循环数组, 获取每个资源 aa[i]
 ​
 •   for (int i = 0; i < aa.length ; i++) {
 ​
 • //   3, 判断资源 是文件夹 还是文件
 ​
 •     if(aa[i].isDirectory()){// 如果是文件夹返回 true
 ​
 • System.out.println(aa[i].getName());//4, 如果是文件夹, 输入文件夹名称
 ​
 •     }
 ​
 else if(aa[i].isFile()){
 ​
 • //   5. 如果是文件 求和.
 ​
 •     sum = sum + aa[i].length() ;
 ​
 •     }
 ​
 •   }
 ​
 •   System.out.println(“ 文件的总大小是:”+sum);
 ​
 • }
 ​
 • }

能够应用父类的办法, 也能够应用本人的扩大办法. 而且还能 new

概述

字节流通罕用来对数据 进行 读写操作.

能够对电脑里的 二进制文件 进行操作.

字节流读 : 是指 从磁盘到 程序 的过程, 是指程序须要读取数据

InputStream

是父类, 而且被润饰成一个抽象类. 不能 new, 咱们只学习父类的共性办法

罕用办法

abstract int read()

从输出流中读取数据的下一个字节。

int read(byte[] b)

从输出流中读取肯定数量的字节,并将其存储在缓冲区数组 b 中。

int read(byte[] b, int off, int len)

将输出流中最多 len 个数据字节读入 byte 数组。

void close()

敞开此输出流并开释与该流关联的所有系统资源。

FileInputStream

能够应用父类的办法, 也能够应用本人的扩大办法. 而且还能 new

FileInputStream 从文件系统中的某个文件中取得输出字节。

创建对象

FileInputStream(String name)

FileInputStream(File file)

BufferedInputStream 缓冲流 / 高级流

能够应用父类的办法, 也能够应用本人的扩大办法. 而且还能 new

在创立 BufferedInputStream 时,会创立一个外部缓冲区数组。

字节流写出

是指从程序到磁盘的过程

OutputStream

此抽象类是示意输入字节流的所有类的超类。

父类被润饰成了抽象类, 不能 new, 只能学习父类提供的共性办法

办法

  void close()
 ​
 • void flush()
 ​
 • void write(byte[] b)
 ​
 • void write(byte[] b, int off, int len)
 ​
 • abstract void write(int b)

FileOutputStream

文件输入流是用于将数据写入 File 或 FileDescriptor 的输入流

子类能够应用 父类的办法, 还能应用本人的扩大办法, 还能 new

FileOutputStream(File file)

FileOutputStream(String name)

FileOutputStream(String name, boolean append)

FileOutputStream(File file, boolean append)

BufferedOutputStream 高级流 / 缓冲流

– 该类实现缓冲的输入流

– 创建对象

BufferedOutputStream(OutputStream out)

泛型

概述

因为汇合中增加的元素类型太丰盛.

如果想要限度汇合中元素的类型 , 就要应用泛型.

泛型是(Generics)是 JDK1.5 的一个新个性,其实就是一个『语法糖』. 标记 <>

益处

– 通过泛型的语法定义,束缚汇合元素的类型,进行安全检查,把谬误显示在编译期

– 代码通用性更强。

能够呈现的地位

– 类上 : public class Student<E>{}

– 办法上: public <E> void eat(E d){}

Collection 接口

概述

Collection 层次结构 中的根接口。Collection 示意一组对象,这些对象也称为 collection 的元素。一些 collection 容许有反复的元素,而另一些则不容许。一些 collection 是有序的,而另一些则是无序的

罕用办法

c.clear(); // 清空集合

System.out.println(c.contains(13) );// 判断 c 里蕴含 13 这个元素吗

System.out.println(c.equals(123) );// 判断 c 是否和 123 相等

System.out.println(c.hashCode() );// 获取 c 在内存中的哈希码值

System.out.println(c.isEmpty() );// 判断 c 是否为空

System.out.println(c.remove(2) );// 移除指定的数据

System.out.println(c.size() );// 获取 c 汇合的长度

// 汇合转数组

Object[] os = c.toArray();// 把 c 里的数据存入数组里

System.out.println(c.addAll(c2) );// 把 c2 加到 c 里去

System.out.println(c.containsAll(c2) );// 判断 c 里蕴含 c2 吗

// 移除 c 中那些也蕴含在 c2 中的所有元素

// System.out.println(c.removeAll(c2) );

// 仅保留 c 中那些也蕴含在 c2 的元素

// System.out.println(c.retainAll(c2) );

Iterator<Integer> it = c.iterator();

//hasNext()- 判断汇合里有元素吗, 有元素就获取, 没有就不取.

while(it.hasNext() ){

Integer in = it.next();

//next()- 把元素获取进去

System.out.println(in);

List 子接口

概述

能够应用父接口 Collection 的所有办法. 也能够有本人的扩大办法.

接口不能被 new, 学习提供的共性办法

特点

– 有序

– 可反复

– 能够存多个 null

– 有索引

罕用办法

– 继承自父接口 Collection 的

略 …

!!! 本人扩大的

void add(int index, E element) 在索引处插入新的值

boolean addAll(int index, Collection<? extends E> c)

E get(int index) 获取下标为 index 的元素

int indexOf(Object o) 获取 o 这个元素第一次呈现的索引值

int lastIndexOf(Object o) 获取 o 这个元素最初一次呈现的索引值

E remove(int index) 移出索引处的元素

E set(int index, E element) 在该索引处,增加元素

List<E> subList(int fromIndex, int toIndex)截取一段汇合

ArrayList

概述

是 List 接口的实现类 . 底层用一个 大小可变的数组 来存放数据的.

创建对象

ArrayList() ​ 结构一个初始容量为 10 的空列表。

LinkedList

概述

是 List 接口的链接列表实现.

创建对象

LinkedList() ​ 结构一个空列表。

罕用办法

list.addFirst(“ 钢铁侠 ”);// 增加首元素 list.addLast(“ 灭霸 ”);// 增加尾元素

System.out.println(list.getFirst() );// 获取首元素 System.out.println(list.getLast() );// 获取尾元素

System.out.println(list.removeFirst() );// 移除首元素 System.out.println(list.removeLast() );// 移除尾元素

Set 接口

概述 一个不蕴含反复元素的 collection。特点 – 不能反复 – 没有索引 – 无序

HashSet

概述 ​ 此类实现 Set 接口, 底层是一个哈希表。它不保障 set 的迭代程序;特地是它不保 证该程序恒久不变。此类容许应用 null 元素。​ 创建对象 ​ HashSet() ​ 结构一个新的空 set,其底层 HashMap 实例的默认初始容量是 16,加载因子是 0.75

特点: 元素不能反复 + 数据无序 + 能够存一个 null

Map 接口

概述

map 里的数据都是一个一个的 键值对 , 当向 map 里存储数据时, 须要指定这条数据的 key 和 value 而且,key 不能反复, 如果反复就会把 value 笼罩掉.

罕用办法

public class Test1_Map {public static void main(String[] args) {//1, 创立 map 对象 Map<Integer,String> map = new HashMap(); //2, 调用办法 //TODO map 的特点: 存的数据都是 键值对模式 + 无序 … map.put(9529,” 石榴姐 ”); map.put(9529,” 如花姐姐 ”); map.put(9528,” 秋香姐 ”); map.put(9527,” 唐伯虎 ”);

 public static void main(String[] args) {
  //1, 创立 map 对象
  Map<Integer,String> map = new HashMap();
  //2, 调用办法
  //TODO map 的特点: 存的数据都是 键值对模式 + 无序 …
  map.put(9529,” 石榴姐 ”);
  map.put(9529,” 如花姐姐 ”);
  map.put(9528,” 秋香姐 ”);
  map.put(9527,” 唐伯虎 ”);
  System.out.println(map);
  //     map.clear();// 清空 map 汇合
  System.out.println(map.containsKey(9529) );// 判断 map 是否蕴含指定的 key
  System.out.println(map.containsValue(“ 唐伯虎 ”) );// 判断 map 是否蕴含指定的 value
  System.out.println(map.equals(123) );// 判断 map 和 123 相等吗
  System.out.println(map.get(9527) );// 依据 key 去 map 里找 value
  System.out.println(map.hashCode() );// 获取哈希码值
  System.out.println(map.isEmpty() );// 判断是否为空
  System.out.println(map.remove(9529) );// 依据 key 删除记录, 并返回 value
  System.out.println(map.size() );// 获取 map 里元素的个数

迭代 map 里的数据: 没提供间接的迭代办法, 须要, 把 map 转成 set, 进而迭代 set 来获取数据.

  //TODO 形式 1: Set<K> keySet() — 把 map 里的 key 存入 set
  // 思路: 调用办法, 把 map 转成 set.
  Set<Integer> set = map.keySet() ;
  // 遍历 set 失去每一个 key.
  for(Integer key : set){
  // 拿着 set 遍历失去的 key 再回 map 里找 value
  String value = map.get(key);
  System.out.println(key +”======”+value);
  }
  //TODO 形式 2: Set<Map.Entry<K,V>> entrySet()– 把 map 里的整条记录封装成 Entry 存入 set
  // 思路: 调用办法, 把 map 转成 set.
  Set<Map.Entry<Integer,String>> set2 = map.entrySet() ;
  // 遍历 set 失去每一个 Entry.
  for(Map.Entry<Integer,String> entry : set2){
  // 再获取 Entry 封装着 key 和 value.
  Integer key = entry.getKey();
  String value = entry.getValue();
  System.out.println(key +”~~~~”+ value);
  }
  //TODO 形式 3: Collection<V> values() — 用的少!
  Collection<String> values = map.values();
  for (String value : values) {
  System.out.println(value);
  }
 ​
 ​

HashMap 实现类

概述

底层为了一个哈希表 / 散列表. ​ 底层在存储数据时, 实质上是向桶里增加数据. 默认容量是 16, 当达到 16 的 0.75 阈值后, 再减少的数据 rehash 开拓新空间

创建对象

HashMap() ​ 结构一个具备默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap。

练习

统计字符串中的字符呈现次数 – 需要: 接管用户输出的一串字符串,统计呈现的每个字符的个数 – 代码 package cn.tedu.api;

  import java.util.HashMap;
  import java.util.Map;
  import java.util.Scanner;
 ​
  // 测试
  // 需要: 接管用户输出的一串字符串,统计呈现的每个字符的个数
  public class Test3_HashMap {
  public static void main(String[] args) {
  //1, 接管用户输出的一串字符串 abcab
  String input = new Scanner(System.in).nextLine();
  // 定义 map, 用来存储数据 {a=2 ,b=2 ,c=1}
  //map 里的 key 是呈现的字符,value 是这个字符呈现了几次
  Map<Character,Integer> map = new HashMap();
  //2, 遍历字符串, 获取每个字符
  for (int i = 0; i < input.length() ; i++) {
  char key = input.charAt(i);
  //3, 统计每个字符的个数 – 并存入 map {a=2 ,b=2 ,c=1}
  Integer value = map.get(key) ;
  //value 的值到底存啥? — 如果存过就 +1, 如果没存过就存 1
  if(value == null){
  value = 1;
  }else{
  value = value + 1;
  }
  // 把筹备好的 key 和 value 存入 map
  map.put(key,value);
  }
  System.out.println(map);
  }
  }

Collections 工具类

概述

此类齐全由在 collection 上进行操作或返回 collection 的静态方法组成。​ –2, 罕用办法 ​ static <T> boolean addAll(Collection<? super T> c, T… elements) ​ 将所有指定元素增加到指定 collection 中。​ static T min(Collection<? extends T> coll) ​ 依据元素的天然程序 返回给定 collection 的最小元素。​ static T max(Collection<? extends T> coll) ​ 依据元素的天然程序 返回给定 collection 的最大元素。​ static void reverse(List<?> list) ​ 反转指定列表中元素的程序。​ static void sort(List<T> list) ​ 依据元素的天然程序 对指定列表按升序进行排序。​ static void swap(List<?> list, int i, int j) ​ 在指定列表的指定地位处替换元素。

测试

package cn.tedu.api;

  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.List;
 ​
  // 测试 汇合工具类 Collections
  public class Test4_Collections {
  public static void main(String[] args) {
  // 用工具类前: 向 List 汇合里增加一些元素
  List<Integer> list = new ArrayList();
  list.add(1);
  list.add(2);
  list.add(3);
  list.add(4);
  list.add(5);
  System.out.println(list);//[1, 2, 3, 4, 5]
  // 用工具类后
  List<Integer> list2 = new ArrayList();
  //TODO 1,addAll()– 用来给指定的 list2 汇合增加一些数据
  Collections.addAll(list2,13,65,82,26,39,61);
  //[13, 65, 82, 26, 39, 61]
  System.out.println(list2);
  //TODO 2,max() 求最大值 min()求最小值
  System.out.println(Collections.max(list2) );
  System.out.println(Collections.min(list2) );
  //TODO 3,reverse() 翻转数据
  Collections.reverse(list2);
  System.out.println(list2);//[61, 39, 26, 82, 65, 13]
  //TODO 4,sort() 排序, 默认从小到大
  Collections.sort(list2);
  System.out.println(list2);//[13, 26, 39, 61, 65, 82]
  //TODO 5,swap() 替换指定地位的两个元素
  Collections.swap(list2,1,4);
  System.out.println(list2);//[13, 65, 39, 61, 26, 82]
  }
  }

多线程

概念

– 过程和线程的区别 ​ — 过程是 正在运行的程序 ​ — 线程是 零碎能够调度的最小单位, 是过程的理论运作单位 ​ 一个软件运行 须要依赖多个过程, 一个过程的运行能够依赖多个线程 ​ – 并行和并发的区别 ​ – 并发是 多个资源 抢占 CPU, 让 CPU 去干活 ​ – 并行是 多个资源要干活, 只不过有多个 CPU 去干活, 基本没产生抢的景象 ​ 多线程是 为了进步程序的执行效率, 是指相当于 把一件事分给 10 集体, 抢着干 — 并发

多线程编程

Thread 类

– 创建对象 ​ Thread() ​ 调配新的 Thread 对象。​ Thread(Runnable target) ​ 调配新的 Thread 对象。​ Thread(Runnable target, String name) ​ 调配新的 Thread 对象。​ Thread(String name) ​ 调配新的 Thread 对象。​ – 罕用办法 ​ static Thread currentThread() ​ 返回对以后正在执行的线程对象的援用。​ long getId() ​ 返回该线程的标识符。​ String getName() ​ 返回该线程的名称。​ void run() ​ 如果该线程是应用独立的 Runnable 运行对象结构的,则调用该 Runnable 对象的 run 办法;​ void setName(String name) ​ 扭转线程名称,使之与参数 name 雷同。​ static void sleep(long millis) ​ 在指定的毫秒数内让以后正在执行的线程休眠 ​ void start() ​ 使该线程开始执行;Java 虚拟机调用该线程的 run 办法。​ void stop() ​ 已过期。该办法具备固有的不安全性。用 Thread.stop 来终止线程

模仿多线程编程

– 继承 Thread 类 ​

 package cn.tedu.thread;
  // 模仿多线程编程
  public class Test2_Thread {
  public static void main(String[] args) {
  //4, 创建对象 MyThread 测试
  MyThread t = new MyThread();
  t.setName(“ 杨幂 ”);// 批改线程名称
  //       t.run();// 只是一个一般的办法调用, 并不能实现多线程的抢占成果. 只是程序执行
  t.start();//TODO 6, 是真正的开启线程, 产生随机性的特点
 ​
 ​
 ​
 •       //TODO 5, 模仿多线程 >= 2
 •       MyThread t2 = new MyThread();
 •       t2.setName(“Anglelababa”);
 • //       t2.run();
 •       t2.start();
 ​
 •       /* 7, 测试失去的后果展现了多线程程序执行的随机性特点: 两个线程始终在抢占 CPU 的执行权
 •           Thread-0====9
 •           Thread-0====10
 •           Thread-1====1
 •           Thread-0====11
 •           Thread-1====2
 •           Thread-0====12
 •           Thread-1====3
 •           Thread-0====13
 •         */
 •   }
 • }
 • //1, 创立自定义的线程类 — 继承 Thread 类
 • class MyThread extends Thread{
 •   //2, 多线程的所有业务代码 , 放入重写的 run() 里 – 右键..generate..override methods..ok
 •   @Override
 •   public void run() {
 • //       super.run();
 •   //TODO 3, 需要: 打印 50 次线程名称
 •       for (int i = 0; i < 50; i++) {
 •           System.out.println(super.getName() +”====”+i );
 •       }
 •   }
 • }

同步锁

- 把有问题的代码加锁 – 同步锁 — 同步是指没钥匙就排队期待的状态. 锁是指把操作共享资源的代码锁起来 — 通过 sychronized 关键字实现

一般办法 会主动调配默认的锁对象 是 this

静态方法 的锁对象会主动调配 是类名.class

如果是一般资源, 锁对象任意只有是同一个锁对象就能够

如果是动态资源, 锁对象 必须是 类名.class

语法

– 能够用在办法上 ​ — public synchronized void append() { ​ – 能够用在代码块上 ​ — synchronized(锁对象){// 这个对象能够任意, 然而, 必须是同一个对象 ​ 有问题的代码 ​}

设计模式

概述

软件设计模式(Design pattern),又称设计模式,是一套被重复应用、少数人通晓的、通过 分类编目标、代码设计教训的总结。应用设计模式是为了可重用代码、让代码更容易被别人了解、保障代码可靠性、程序的重用性。

单例模式(Singleton)

保障一个类仅有一个实例,并提供一个拜访它的全局拜访点。模仿单例设计模式

  package cn.tedu.design;
 • // 模仿 – 23 种设计模式里的 单例设计模式 – 保障一个类仅有一个对象
 • // 单例模式 :
 • //1, 私有化构造方法, 不能让外界随便 new
 • //2, 在类的外部, 本人 new 好一个对象, 让外界用
 • //3, 提供一个全局的拜访点 get(), 用来获取 new 好的对象
 • // 益处是 : 管制外界 new 的权力, 节俭内存节省时间 –SSM 大量应用
 • public class Test1_Singleton {
 •   public static void main(String[] args) {
 •       Person p1 = Person.getP();//5, 调用静态方法, 应用对象
 •       Person p2 = Person.getP();
 •       System.out.println(p1 == p2);//true
 ​
 •       Student s1 = Student.getS();
 •       Student s2 = Student.getS();
 •       System.out.println(s1 == s2);//true
 •   }
 • }

懒汉式 – 面试的重点!!! — 提早加载 + 线程不平安

 class Student{
  //1, 私有化结构
  private Student(){}
  //2, 本人申明一个对象
  static private Student s ; //null
  //3, 对外提供的一个 get()
  synchronized static public Student getS() {
 // 4, 在多线程编程中, 共享资源 s, 被多条语句操作, 肯定会有安全隐患 — 必须加锁
 // 锁加在 同步办法或者同步代码块都能够,
 // 如果共享资源是动态资源, 那么, 锁对象必须 固定是 类名.class
 // 如果办法是一般办法锁对象默认是 this, 如果是动态方锁对象默认是类名.class
  //       synchronized (Student.class){
  if(s == null){
 // 如果是默认值 null, 就创建对象 – 保障了单例!!
  s = new Student();
  }
  return s;
  //       }
  }
  }

饿汉式 – 学习工作中应用的形式!!!

 class Person{
  //1, 私有化构造方法 — 不让外界轻易 new
  private Person(){}
 ​
 • //2, 在 类的外部 提供一个 new 好的对象
 • // 加 static — 因为动态只能调用动态, 所以, 想要被动态的 getP() 调用, 必须润饰成动态的
 •   static private Person p = new Person();
 ​
 •   //3, 提供公共的拜访形式 getXxx(), 获取 p 对象
 • // 加 static — 目前无奈通过创建对象来调用 getP(), 所以变成动态的, 间接通过类名来调用 getP()
 •   static public Person getP(){
 •       return p ;// 把创立好的对象 p, 返回给调用地位
 •   }
 • }

反射

概述

Reflection(反射) 是 Java 程序开发语言的特色之一,它容许运行中的 Java 程序对本身 进行查看,或者说“自审”,也有称作“自省”。反射十分弱小,它甚至能间接操作程序的公有属性。咱们后面学习都有一个概念,private 的只能类外部拜访,内部是不行的,但这个规定被反射 赤裸裸的突破了。

反射就像一面镜子,它能够在运行时获取一个类的所有信息,能够获取到任何定义的信息(包 括成员变量,成员办法,结构器等),并且能够操纵类的字段、办法、结构器等局部。– 实质 ​ JVM 利用反射技术, 来解析.class 文件里的所有数据, 包含 公开的和公有的 成员变量 / 成员方 法 / 构造方法 /….. 并把所有获取到的资源, 封装起来造成 Class 工具类. ​ 而后通过 Class 工具类提供了各种办法来解析获取各种 … – 开发思路 ​ – 获取 Class 对象 ​ – 通过 Class 工具类提供的各种办法来后去所有资源 – 获取 Class 对象的形式 ​ –Class.forName(“类的全门路”); ​ – 类名.class ​ – 对象.getClass();

创立 Demo 类

package cn.tedu.reflect;

  import org.junit.Test;
 ​
  // 测试 反射
  public class Demo {
  public Demo(){}
  public Demo(String name) {
  this.name = name;
  }
  public Demo(String name, int age) {
  this.name = name;
  this.age = age;
  }
  public String name;
  public int age;
 ​
  @Test
  public void show(){
  System.out.println(“show”);
  }
  public void save(int id){
  System.out.println(“ 保留胜利!”);
  }
  }

创立测试类

 package cn.tedu.reflect;
  import java.lang.reflect.Constructor;
  import java.lang.reflect.Field;
  import java.lang.reflect.Method;
  import java.util.Arrays;
  // 反射 Demo 类里的资源
  // 总结
  // 原理是 :
  //1, 通过 类的加载器 把 java 里的类, 加载进内存. 而后通过编译器, 把.java 文件编译变成.class 文件
  //2,JVM 拿到你的.class 文件, 开始解析外面的所有资源 . 把.class 文件封装成 Class 对象
  //3, 通过 Class 工具类提供的各种 getXxx() 获取各种资源
 ​
 • // 用过 Class 工具类的办法:
 • //1,getConstructors() — 获取所有的   公开的 构造方法们~~~
 • //2,getFields() — 获取所有的 公开的 成员变量们~~~
 • //3,getMethods() — 获取所有的 公开的 成员办法们~~~
 ​
 • public class Test1_Reflect {
 •   public static void main(String[] args) throws Exception {
 • //       method();// 反射.class 里的构造方法
 • //       method2();// 反射.class 里的 一般办法
 • //       method3();// 反射.class 里的 成员变量
 •       method4();// 利用反射创建对象
 •   }
 •   // 利用反射创建对象
 •   public static void method4() throws Exception {
 •       //1, 反射 Class 对象
 •       Class a = Demo.class;
 •       //2, 创建对象
 •       //newInstance() 默认返回的是 Object 父类类型
 •       Object d = a.newInstance();// 默认会触发无参结构
 • //     Demo d = (Demo)a.newInstance(); 为了用子类的特有性能
 •       //cn.tedu.reflect.Demo@677327b6
 •       System.out.println(d);
 •   }
 •   // 反射.class 里的 成员变量
 •   public static void method3() {
 •       //1, 获取 Class 对象
 •       Class a = Demo.class;
 •       //2, 获取 所有 公共的 成员变量们~
 •       Field[] fs = a.getFields();
 •       //3, 获取每个 成员变量 f
 •       for (Field f : fs) {
 •           //4, 获取 变量名
 •           System.out.println(f.getName() );
 •           //5, 获取 变量类型
 •           System.out.println(f.getType().getName());
 •       }
 •   }
 •   // 反射.class 里的 一般办法
 •   public static void method2() {
 •       //1, 获取 Class 对象
 •       Class a = Demo.class;
 •       //2, 反射所有 公开的 办法们~~~
 •       // 本人的和父类的
 •       Method[] ms = a.getMethods();
 •       //3, 获取 每个办法 m
 •       for (Method m : ms) {
 •           //4, 获取 办法名
 •           System.out.println(m.getName() );
 ​
 •           //5, 获取 办法的参数类型
 •           Class[] css = m.getParameterTypes();
 •           System.out.println(Arrays.toString(css) );
 •       }
 •   }
 •   //TODO 反射.class 文件里的 构造方法
 •   public static void method() {
 •       //1, 反射 class 对象
 •       Class a = Demo.class ;
 •       //2, 获取所有 构造方法们 ~
 •       Constructor[] cs = a.getConstructors();
 •       //3, 获取每个构造方法 x
 •       for(Constructor x : cs){
 •           //4, 获取 x 的 参数类型们 ~
 •           Class[] css = x.getParameterTypes();
 •           System.out.println(Arrays.toString(css) );
 •       }
 •   }
 • }

暴力反射

概述

把.class 文件里的 所有数据获取到. 包含 public 的 和 private 的 新的 API ​ getDeclaredFields() — 获取 所有 成员变量 ​ getDeclaredField() — 获取 指定的 成员变量 ​ getDeclaredMethods() — 获取 所有 成员办法 ​ getDeclaredMethod() — 获取 指定的 成员办法 ​ getDeclaredConstructors() — 获取 所有 构造方法 ​ getDeclaredConstructor() — 获取 指定的 构造方法

创立 Student 类

 package cn.tedu.reflect;
  import org.junit.Test;
  // 测试 暴力反射
  public class Student {
  public String name;
  private int age ;
 ​
 •         public void show(){
 •       System.out.println(“show()”);
 •   }
 ​
 •   public void save(int a){
 •       System.out.println(“ 保留胜利!”);
 •   }
 •   private void get(String a){
 •       System.out.println(“ 保留胜利!”+a);
 •   }
 •   private void delete(int id){
 •       System.out.println(“ 删除胜利!”+id);
 •   }
 }

创立测试类

  package cn.tedu.reflect;
 • import org.junit.Test;
 • import java.lang.reflect.Field;
 • import java.lang.reflect.Method;
 • import java.util.Arrays;
 • // 测试 暴力反射
 • // 总结:
 • //1, 暴力反射 能够获取.class 文件里的 public 和 private 资源
 •
 • public class Test2_Baoli {
 •   public static void main(String[] args) throws Exception {
 • //       method();// 暴力反射 所有成员办法
 • //       method2();// 暴力喷射 指定办法并执行
 • //       method3();// 练习
 • //       method4();// 暴力反射 所有成员变量
 • //       method5();// 暴力反射 指定成员变量
 •       method6();// 执行 注解办法
 •   }
 •
 ​

 private static void method6() throws Exception {
 •       //1, 获取 Class 对象
 •       Class a = Student.class;
 •       Object o = a.newInstance();
 •       //2, 获取所有办法
 •       Method[] ms = a.getDeclaredMethods();
 •       //3, 遍历失去每个办法 m
 •       for (Method m : ms) {
 •           //4, 获取 指定的 Test 注解 – 参数就是注解的 Class
 •           Test test = m.getDeclaredAnnotation(Test.class);
 •           //5, 判断哪些有 就 invoke() 执行
 •           if(test != null){
 •               //invoke(m,n)- m 是对象名 - n 是要给办法传递的参数
 •               m.invoke(o,null);
 •           }
 •       }
 •   }

  //TODO 暴力反射 指定成员变量
 •   private static void method5() throws Exception {
 •       Class a = Student.class;
 •       //1, 依据变量名获取 指定的变量 f
 •       Field f = a.getDeclaredField(“age”);
 •       f.setAccessible(true);// 设置公有的拜访权限!!!
 ​
 •       //2,set() 设置值
 • // 第一个参数是 指定的对象名 第二个参数是 要给属性设置的值
 •       Object o = a.newInstance();
 •       f.set(o,100);
 •       //3,get() 获取值 — 须要指定要获取哪个对象的
 •       System.out.println(f.get(o) );
 •   }

 // 暴力反射 所有成员变量
 •   private static void method4() {
 •       //1, 获取 Class 对象
 •       Class a = Student.class;
 •       //2, 获取 所有 成员变量们~
 •       Field[] fs = a.getDeclaredFields();
 •       //3, 获取每个 成员变量 f
 •       for (Field f : fs) {
 •           //4, 获取 变量名
 •           System.out.println(f.getName() );
 •           //5, 获取 变量类型
 •           System.out.println(f.getType().getName());
 •       }
 ​
 •   }

  public static void method3() throws Exception {
 •       Class a = Student.class;
 • Method m = a.getDeclaredMethod(“delete”, int.class);
 •       m.setAccessible(true);// 设置公有的拜访权限
 ​
 •       Object o = a.newInstance();
 •       m.invoke(o,10);// 执行指定办法
 •   }
 •

 // 暴力喷射 指定办法并执行
 •   public static void method2() throws Exception {
 •       //1, 获取 Class 对象
 •       Class a = Student.class;
 •       //2, 获取指定的某个办法
 •       // 第一个参数是 指定的办法名称
 •       // 第二个参数是 该办法须要的参数类型的 Class 对象
 •       Method m = a.getDeclaredMethod(“get”,String.class) ;
 ​
 •       m.setAccessible(true);// 开启拜访权限!!!!!!!
 •       //3, 让办法执行起来 invoke
 •       // 第一个参数是 指定对象
 •       // 第二个参数是 指定给该办法传入的参数
 •       Object o = a.newInstance();
 •       m.invoke(o,”hello”);
 •   }

 //TODO 暴力反射成员办法 getDeclaredMethods()
 •   public static void method() {
 •       //1, 获取 Class 对象
 •       Class a = Student.class;
 •       //2, 反射所有 办法们~~~
 •       Method[] ms = a.getDeclaredMethods();
 •       //3, 获取 每个办法 m
 •       for (Method m : ms) {
 •           //4, 获取 办法名
 •           System.out.println(m.getName() );
 ​
 •           //5, 获取 办法的参数类型
 •           Class[] css = m.getParameterTypes();
 •           System.out.println(Arrays.toString(css) );
 •       }
 •   }
 • }
 ​
 ​

反射的练习

创立 Person 类

  // 练习反射
  public class Person {
  String name;
  private int age ;
  public void save(int id){
  System.out.println(“save..”+id);
  }
  private void delete(int id){
  System.out.println(“delete..”+id);
  }
  }

创立测试类

  import java.lang.reflect.Field;
  import java.lang.reflect.Method;
 ​
  // 练习反射
  public class Test3_Person {
  public static void main(String[] args) throws Exception {
  // 获取 Class 对象
  Class a = Person.class ;
  //       method(a);// 反射属性并 set()/get()
  method2(a);// 反射办法并运行
  }
  // 反射办法并运行
  private static void method2(Class m) throws Exception {
  // 反射 指定的 公有办法
  Method me = m.getDeclaredMethod(“delete”,int.class);
  // 设置拜访权限 !!!!
  me.setAccessible(true);
  // 执行办法
  Object o = m.newInstance();
  me.invoke(o,200);
  }
  // 反射属性并 set()/get()
  private static void method(Class m) throws Exception {
  // 属性被封装无奈间接用, 能够通过反射操作 ~~~
  //       new Person().age = 20 ;
  // 反射 指定名称的 属性
  Field f = m.getDeclaredField(“age”);
  // 设置公有的拜访权限 !!!!
  f.setAccessible(true);
  // 利用反射创建对象
  Object o = m.newInstance();
  // 给属性设置具体值
  f.set(o,66);
  // 获取属性值
  System.out.println(f.get(o) );
  }
  }

外部类

概述

外部类 是为了 给外部类服务的. 构造 ​ class A{// 外部类 ​

class B{// 外部类 — 看做是 A 类的一个非凡的成员 ​ ​} ​ } 特点 ​ – 外部类 随着地位的不同, 名字和作用都不同 ​ – 在成员地位 (类里办法外) 的外部类, 叫成员外部类 ​ – 在部分地位 (办法里) 的外部类, 叫部分外部类 ​ – 在内部类 应用 外部类的资源 – 间接应用 ​ – 在外部类 应用 外部类的资源 — 创立外部类对象拜访 !!

入门案例

 package cn.tedu.inner;
  // 测试 外部类
  public class Test3_Inner {
  public static void main(String[] args) {
  //1, 想用外部类的资源 – 创立外部类的对象
  // 外部类名. 外部类名 变量名 = 外部类对象. 外部类对象
  Outer.Inner oi = new Outer().new Inner();
  System.out.println(oi.age);
  oi.in();
  }
  }

 class Outer{// 外部类
  String name ;
  public void out(){
  //TODO 3, 在外部类 应用 外部类的资源 — 创立外部类对象拜访 !!
  System.out.println(new Inner().age );
  System.out.println(“out..”);
  }
  class Inner{// 外部类 – 在成员地位的外部类是成员外部类
  int age;
  public void in(){
  //TODO 2, 在内部类 应用 外部类的资源 – 间接应用
  out();
  System.out.println(“in..”);
  }
  }
  }

匿名外部类

  public class Test4_Inner {
  public static void main(String[] args) {
 
  new Inter(){// 相当于创立了接口的对象
  @Override// 重写了接口里的办法
  public void save() {
  System.out.println(“save()”);
  }
  }.save();// 调用了指定的办法
  //TODO
  new Inter2(){
  @Override
  public void update(int id) {
  System.out.println(“ 更新数据胜利,id 是:”+id);
  }
  }.update(10);
  //TODO
  Inter3 in = new Inter3(){
  @Override
  public void update(int id) {
  System.out.println(“ 更新胜利,id 是:”+id);
  }
  @Override
  public void delete(int id) {
  System.out.println(“ 删除胜利,id 是:”+id);
  }
  };
  in.delete(10); // 匿名对象干一个活儿, 那就给对象起个名字干好多活儿
  in.update(5);

  interface Inter{
  // 能够简写, 会主动拼接 public abstract
  void save();
  }
 ​
 interface Inter2{
  void update(int id);
  }
 ​
 interface Inter3{
  void update(int id);
  void delete(int id);
  }

退出移动版