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