概述
所有能够调用的都是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);
}
发表回复