java新高级特性 @Draven
- 集合框架
- List 接口储存不唯一,有序的对象
- Set 接口储存唯一,无序的对象
- Map 接口储存一组键值对象,提供Key到value的映射
- 遍历输出集合
- 增强版遍历输出
- Map
- Iterator -->迭代器
-
- 泛型集合
- String实用类
- String 和 StringBuffer
- Math类
- Random
- Random rand = new Random()
- Date
-
- IO流
-
- 字符流
- 字符输入流
- 字符输出流
- 写入效率高的写法
- 写入二进制文件
- 可复制图片 代码如下
- 多线程
-
- 网络编程
- Socket传输String
- Socket传输对象
- Socket线程使用
- UDP协议的Socket编程
- XML
- 获取整个XML文档对象
- 显示文档内容信息
- 保存xml文件
- 添加节点
- 修改节点
- 删除节点
- DOM4J1-6-1
- 获取整个xml文档
- 显示所有信息
- 保存xml文件
- 添加节点
- 修改节点
- 删除节点
- 反射机制
-
- 注解
- 简介:注解是java代码里的特殊标记,为java程序代码提供了一种形式化的方法、
- 注解以标签的形式存在于java代码中、注解的存在并不影响程序代码的编译和执行,
- 他只是用来生成其他文件或使我们在运行代码时知道 被运行代码的描述信息
集合框架
List 接口储存不唯一,有序的对象
Set 接口储存唯一,无序的对象
Map 接口储存一组键值对象,提供Key到value的映射
| ArrayList: | 声明方式: ArrayList name = new ArrayList( ); |
|---|
| Set: | 声明方式: Set set = new HashSet(); |
| .add() | 向集合添加新元素 |
|---|
| .addFirst() | 在集合第一位添加元素 |
| .addLast() | 在集合最后一位添加元素 |
| .contains() | 检测集合中是否包含括号内的元素 返回值为boolean |
| |
| .remove() | 括号填下标 删除括号下标的元素 |
| .removeFirst() | 删除首位元素 |
| .removerLast() | 删除末尾元素 |
| 在Map集合中 括号内填键名进行删除 |
| .get() | 获取元素 |
| .getFirst() | 获取首位元素 |
| .getLast() | 获取末尾元素 |
| |
| .set(下标,内容) | 替换掉刻下标的内容 |
| .clear() | 清空集合中的数据元素 |
| .size() | 返回、查询 集合中的元素个数 |
| .isEmpty() | 判断是否是一个空集合 返回值为boolean |
| Collections.sort© | 对集合字符或数字进行排序 |
遍历输出集合
for (int i = 0; i < list.size(); i++) {
String name = (String) list.get(i);
System.out.println(i+"t"+name);
}
增强版遍历输出
for (Object obj:list){
NewTitle n = (NewTitle) obj;
System.out.println(n.getTitlename());
}
Map
| .put(“键”,对象) | 添加数据 |
|---|
| .keySet() | 输出键集合 |
| .containsKey(对象/变量或键) | 判断括号内的数据是否存在 |
String key1 = "键";
if(集合名.containsKey(key1)){
sout(key1+"的信息:"+集合名.get(key1))
}
通过键进行删除操作
集合名.remove("键")
Iterator -->迭代器
Map两种遍历使用
增强for循环 迭代器的使用
增强for循环
//声明一个Map集合
Map maps = new HashMap();
//添加数据
maps.put("1","张三");
maps.put("2","李四");
maps.put("3","王五");
maps.put("4","麻子");
//获取键集合
Set keys =maps.keySet();
//增强for循环
for (Object obj:keys){
String strkey = obj.toString();
String value = maps.get(strkey);
System.out.println(strkey+"t"+value);
}
迭代器循环
//声明一个Map集合
Map maps = new HashMap();
//添加数据
maps.put("1","张三");
maps.put("2","李四");
maps.put("3","王五");
maps.put("4","麻子");
//获取键集合
Set keys =maps.keySet();
//获取迭代器集合
Iterator iterator = keys.iterator();
//开始迭代
while (iterator.hasNext()){
String key = (String) iterator.next();
String value = maps.get(key);
System.out.println(key+"t"+value);
}
泛型集合
| 特点: | 泛型集合 可以定义添加数据的类型 方便之处在于不需要强转 就可以直接获取数据 |
|---|
| 语法: | |
List list = new ArrayList<>();
//添加数据
Student s = new Student("张三","男");
list.add(s);
//获取对象
System.out.println(list.get(0).getName());
String实用类
| .length() | 检测字符串长度 |
|---|
| .equals(值) | 检查字符串与括号里的值是否完全一致 返回值为boolean |
| .trim() | 去掉字符串前后的空格 |
| |
| .toLowerCase() | 将字符串全部转换为小写 |
| .toUpperCase() | 将字符串全部转换为大写 |
| .equalsIgnoreCase(值) | 使用该方法比较字符串 可忽略大小写 |
| |
| .indexOf(“值”) | 检测该字符串中是否包含此值 查找的是第一次出现的位置的下标 如果没有此值返回-1 |
| .lastIndexOf(“值”) | 查找的是最后一次出现的位置的下标 |
| |
| .substring(角标,角标) | 截取字符串中的内容 从第一个角标开始到截止角标(包前不包后) |
| .split(“字符”) | 寻找括号中的字符 如果找到该字符 则自动删除该字符并将字符前内容储存到数组 |
| 需要用数组来接收 String[] arr = a.split("、"); |
String 和 StringBuffer
| String是不可变对象 |
|---|
经常改变内容的字符串最好不要用String StringBuffer 是可变的字符串 字符串经常改变的情况下 使用StringBuffer 更高效 JDK1.5后提供了StringBuilder 等价于 StringBuffer |
| 声明方式: | StringBuffer name = new StringBuffer(字符串); |
|---|
| .concat(字符) | 在该变量字符后面追加字符变量 |
| .append(“字符串”) | 会将括号内的字符串添加到StringBuffer 声明的变量中 |
| .insert(下标,“字符”) | 通过下标来添加字符 后面元素自动往后推 |
| .replace(原字符,替换字符) | 将原字符替换成需要替换的字符 |
Math类
| Math.abs(自然数) | 会将括号内的数进行绝对值操作 如-2 自动转换为 2 |
|---|
| Math.max(数,数) | 会将括号内的两个数作比较 然后返回最大的数 如0.21 99 返回99 |
| Math.min(数,数) | 会将括号内的两个数作比较 然后返回最大的数 如0.21 99 返回0.21 |
Random
Random rand = new Random()
Date
| .YEAR | 获取当前的年份 |
|---|
| .MONTH | 获取当前的月份,从0开始 |
| .DAY_OF_MONTH | 获取今天是这个月的第几天 |
| .DAY_OF_YEAR | 获取今天是这一年的第几天 |
实例操作步骤
1.实例化日期对象
Date date = new Date();
2.实例化日期格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
3.接受当前日期
String format = sdf.format(date);
4.输出当前时间
System.out.println(date)
一、 实例化日历对象
Calendar cld = Calendar.getInstance();
二、 获取日期特定部分
//年
System.out.println(cld.get(cld.YEAR));
//月(从0开始)
System.out.println(cld.get(cld.MONDAY));
//日(这个月的第几天)
System.out.println(cld.get(cld.DAY_OF_MONTH));
//日(这一年的第几天)
System.out.println(cld.get(cld.DAY_OF_YEAR));
IO流
File
| .exists() | 判断该文件是否存在 |
|---|
| .delete() | 删除该文件 |
| .isFile() | 判断是否是文件 |
| .getName() | 获取文件名 |
| .getPath() | 获取相对路径 |
| .getAbsolutePath() | 获取绝对路径 |
| .length() | 获取文件大小 (字节长度) |
| .isDirectory() | 判断是否是目录 |
| .createNewFile() | 创建该文件 注: 需try catch包含 |
try {
file.createNewFile();
System.out.println("文件已创建");
} catch (IOException e) {
e.printStackTrace();
}
字节输入流
| 流 是指一连串流动的字符,是以先进、先出方式发送信息的通道 字节流是8位通用字节流,字符流是16位Unicode字符流 |
|---|
OutputStream和Writer作为基类
| 声明方式 | FileInputStream file = new FileInputStream(“读取输入路径”); |
|---|
| .available() | 读取字节数 |
| .read() | 从输入流中读取数据的下一个字节 如果已经没有可用的字节,则返回-1 |
| .close() | 关闭读取操作 在finally中声明 |
字节输出流
InputStream和Reader作为基类
| 声明方式 | FileOutputStream file = new FileOutputStream(输入路径) |
|---|
| .getBytes() | 返回值为byte[]数组 得到一个ASCII编码格式的字节数组 |
| 假设一个字符串 str=“abc” byte[] bytes = str.getBytes[] 则bytes[0]=97 , bytes[1]=98 , bytes[2]=99 |
| .write(byte[] , 起始位置(0) , 结束位置(byte[].length)) | 写入数据 |
| write每次读取10个字节 若字节位46 则多出4字节 以获取的长度为结束位置则可避免该问题 |
自写程序 复制文件内容
FileInputStream file = null;
FileOutputStream file1 = null;
File file2 = null;
try {
//创建输出流对象 用于读取文件对象创建
file = new FileInputStream("E:\javaWorkSpace\高级特效\第三章IO\src\字节输出流\text.txt");
//创建输入流对象 用于对目标文件写入数据
file1 = new FileOutputStream("E:\javaWorkSpace\高级特效\第三章IO\src\复制文本文件\text.txt");
//判断是否有该文件
file2 = new File("E:\javaWorkSpace\高级特效\第三章IO\src\复制文本文件\text.txt");
byte[] words = new byte[file.available()];
//如果没有目标文件 则自动创建
if (!file2.exists()){
System.out.println("您的目录下没该文件 已自动为您创建");
file2.createNewFile();
}
//写入文件操作
while ((file.read(words))!=-1){
file1.write(words , 0 , words.length);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
file.close();
file1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
字符流
字符输入流
| 声明方式 | FileReader fr = new FileReader(读取路径); |
|---|
| .readLine() | 读取数据 以字符串形式返回这一行的数据 |
| 当读取完所有的数据时会返回null。 |
| .replace(原字符,新字符) | 第一个字符为查找的字符 第二个字符为查找后 需要替换成的字符 |
| 输出文档内容: | |
ileReader fr = null;
try {
//创建FileReader对象
fr = new FileReader("E:\javaWorkSpace\高级特效\第三章IO\src\字符输入流\text.txt");
//创建字符数组作为中转站
char[] ch = new char[1024];
//用于临时储存读取的数据
StringBuffer sbf = new StringBuffer();
int length = -1;
//开启循环
while ((length = fr.read(ch))!=-1){
sbf.append(ch); //追加
}
//输出
System.out.println(sbf.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}finally {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
每次读取一行 效率较高
| FileReader fr = new FileReader(); |
|---|
| BufferedReader bf = new BufferedReader(fr); |
FileReader fr = null;
BufferedReader bf = null;
try {
//创建对象
fr = new FileReader("E:\javaWorkSpace\高级特效\第三章IO\src\复制文本文件\text.txt");
bf = new BufferedReader(fr);
String line = null;
//开启循环
while (( line = bf.readLine())!=null){
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fr!=null){
fr.close();
}
if (bf!=null){
bf.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
字符输出流
| FileWriter fw = new FileWriter(目标文件路径); |
|---|
| .flush() | 刷新缓冲区 |
|---|
| .write() | 写入字段 |
| .toString() | 转换为字符串输出 |
try {
//创建一个FileWriter文件
fw = new FileWriter("E:\javaWorkSpace\高级特效\第三章IO\src\字符输出流\text.txt");
fw.write("姚小煜");
fw.flush();//刷新缓冲区
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
写入效率高的写法
| FileReader fr = new FileReader(); |
|---|
| BufferedReader bf = new BufferedReader(fr); |
BufferedWriter bf = null;
FileWriter fw = null;
try {
fw= new FileWriter("E:\javaWorkSpace\高级特效\第三章IO\src\字符输出流\text.txt");
bf = new BufferedWriter(fw);
bf.write("你好");
bf.newline(); //换行
bf.write("好久不见");
bf.newline();
bf.write("最近还好么");
bf.flush(); //刷新缓冲区
System.out.println(bf.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
写入二进制文件
可复制图片 代码如下
FileInputStream fis = null;
DataInputStream dis = null;
FileOutputStream fos = null;
DataOutputStream dos = null;
try {
//创建输入流对象
fis = new FileInputStream("E:\javaWorkSpace\高级特效\第三章IO\src\写二进制文件\text.jpg");
dis = new DataInputStream(fis);
//创建输出流对象
fos = new FileOutputStream("E:\javaWorkSpace\高级特效\第三章IO\src\写二进制文件\刘振阳.jpg");
dos = new DataOutputStream(fos);
//开始读写二进制
int temp;
while ((temp = dis.read())!=-1){
dos.write(temp);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fis!=null){
fis.close();
}
if (dis!=null){
dis.close();
}
if (fos!=null){
fos.close();
}
if (dos!=null){
dos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
多线程
Thread类
编写简单,可直接操作线程 适用于单继承 前提条件: 需要在方法类里继承 extends Thread |
|---|
| 声明方式 Thread t = new Thread(new 类名(),“线程A”); |
|---|
| .start() | 开启线程 |
|---|
| .currentThread() | 返回正在被执行的线程信息 |
| .getName() | 获取线程名字 |
| .setName(“MyDraven”) | 修改线程名字 |
| .join() | 强制执行 需要try |
| .setPriority() | 线程执行优先级 概率优先并非绝对 |
| .sleep() | 线程的睡眠 括号内的值为毫秒:每运行一次休息多少毫秒 |
| .yield() | 线程礼让 概率性再某次执行过程中处于就绪状态 先让别的线程执行 |
Runnable接口
避免单继承局限性 便于共享资源 主推荐 前提条件: 需要在方法类里使用接口 implements Runnable 重写run方法 在方法类里面需要使用Thread调用方法 |
|---|
//创建子线程对象
MyDravem s = new MyDravem();
//Thread线程类对象
Thread t = new Thread(s);
//开启子线程
t.start();
网络编程
Socket传输String
服务器
try {
//创建服务器Socket 指定端口并开始监听
ServerSocket serverSocket = new ServerSocket(8800);
//通过accept等待客户端触发通信
Socket socket = serverSocket.accept();
//打开输入流输出流
InputStream is =socket.getInputStream();
//获取客户端信息
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String info = null;
while (!((info = br.readLine())==null)){
System.out.println("我是服务器,客户端登录信息为:"+info);
}
br.close();
is.close();
socket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
客户端
//创建客户端Socket连接 用来指定服务器的位置以及端口
try {
Socket socket = new Socket("localhost",8800);
//打开输入输出流
OutputStream os = socket.getOutputStream();
//准备信息
String info="用户名: tom 密码: 123456";
os.write(info.getBytes());
//关闭资源
os.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
Socket传输对象
服务器
try {
//创建服务器Socket 指定端口并开始监听
ServerSocket serverSocket = new ServerSocket(8800);
//通过accept等待客户端触发通信
Socket socket = serverSocket.accept();
//打开输入流输出流
InputStream is =socket.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
User user = (User)ois.readObject();
System.out.println("我是服务器 接收到的信息:"+user.getUserName()+"--"+user.getPWB());
is.close();
socket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
客户端
//创建客户端Socket连接 用来指定服务器的位置以及端口
try {
Socket socket = new Socket("localhost",8800);
//打开输入输出流
OutputStream os = socket.getOutputStream();
User u = new User("TOM","123456");
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(u);
socket.shutdownOutput();
String info="用户名: tom 密码: 123456";
os.write(info.getBytes());*/
//关闭资源
oos.close();
os.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
方法类 调用 Serializable 接口
public class User implements Serializable {
//属性
private String userName;
private String PWB;
public User(String userName, String PWB) {
this.userName = userName;
this.PWB = PWB;
}
public User() {
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPWB() {
return PWB;
}
public void setPWB(String PWB) {
this.PWB = PWB;
}
}
Socket线程使用
服务器
try {
//创建服务器Socket 指定端口并开始监听
ServerSocket serverSocket = new ServerSocket(8800);
//通过accept等待客户端触发通信
Socket socket = null;
//监听一直在进行
while (true){
socket = serverSocket.accept();
LoginThread loginThread = new LoginThread(socket);
loginThread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
客户端
//创建客户端Socket连接 用来指定服务器的位置以及端口
try {
Socket socket = new Socket("localhost",8800);
//打开输入输出流
OutputStream os = socket.getOutputStream();
User u = new User("TOM","1213456783");
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(u);
socket.shutdownOutput();
String info="用户名: tom 密码: 123456";
os.write(info.getBytes());*/
//关闭资源
oos.close();
os.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
线程类
public class LoginThread extends Thread{
Socket socket = null;
//每启动一个线程 都需要想对象的Socket
public LoginThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
InputStream is =socket.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
User user = (User)ois.readObject();
System.out.println("我是服务器 接收到的信息:"
+user.getUserName()+"--"+user.getPWB());
is.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
UDP协议的Socket编程
服务器
byte[] infos = new byte[1024];
//服务器
DatagramSocket socket = null;
try {
DatagramPacket dp = new DatagramPacket(infos , infos.length);
socket = new DatagramSocket(5000);
//接受客户端的数据包
socket.receive(dp);
String info = new String(dp.getData(),0,dp.getData().length);
System.out.println(dp.getAddress().getHostAddress()+"说: "+info);
} catch (IOException e) {
e.printStackTrace();
} finally {
socket.close();
}
客户端
DatagramSocket socket = null;
//客户端
String info = "你好我想资讯一个问题";
byte[] infos = info.getBytes();
try {
InetAddress ia = InetAddress.getByName("localhost");
DatagramPacket dp = new DatagramPacket(infos,infos.length,ia,5000);
//客户端使用Socaet对象
socket = new DatagramSocket();
//通过DatagramSocket 对象发送数据包到服务器中
socket.send(dp);
} catch (UnknownHostException | SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
socket.close();
}
XML
获取整个XML文档对象
| private document document = null; |
|---|
public void getdocument(){
//创建解析器工厂对象
documentBuilderFactory factory = documentBuilderFactory.newInstance();
//创建解析器对象
documentBuilder builder = factory.newdocumentBuilder();
document = builder.parse("收藏信息.xml");
}
显示文档内容信息
public void shouInfo(){
//获取Brand标签
NodeList brands = document.getElementsByTagName("Brand");
for (int i = 0; i < brands.getLength(); i++) {
Node node = brands.item(i);
Element eleBrand = (Element) node;
//输出nama标签的值
System.out.println(eleBrand.getAttribute("name"));
NodeList types = eleBrand.getChildNodes();
for (int j = 0; j < types.getLength(); j++) {
Node typeNode = types.item(j);
if (typeNode.getNodeType()==Node.ELEMENT_NODE){
Element eleType = (Element) typeNode;
//输出nama标签的值
System.out.println(eleType.getAttribute("name"));
}
}
}
}
保存xml文件
public void saveXML(String path){
//创建转换器工厂
TransformerFactory factory = TransformerFactory.newInstance();
//设置缩进
factory.setAttribute("indent-number","4");
//创建转换器对象
Transformer transformer = factory.newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING,"UTF-8");
//设置缩进
transformer.setOutputProperty(OutputKeys.INDENT,"yes");
//创建StreamReasult对象
StreamResult result = new StreamResult(new OutputStreamWriter(new FileOutputStream(path),"utf- 8"));
//创建DomSource对象
DOMSource source = new DOMSource(document);
//开始转换
transformer.transform(source,result);
}
添加节点
public void add(){
//创建Brand元素
Element element = document.createElement("Brand");
element.setAttribute("name","三星");
//创建Type元素
Element typee = document.createElement("Type");
typee.setAttribute("name","Note10");
//将Type元素放入Brand中
element.appendChild(typee);
//将Brand元素存入根节点中
document.getElementsByTagName("PhoneInfo").item(0).appendChild(element);
this.saveXML("new.xml");
}
修改节点
public void update(){
NodeList brands = document.getElementsByTagName("Brand");
for (int i = 0; i < brands.getLength(); i++) {
Node brand = brands.item(i);
Element eleBrand = (Element) brand;
if (eleBrand.getAttribute("name").equalsIgnoreCase("三星")){
eleBrand.setAttribute("name","OPPO");
}
}
this.saveXML("new.xml");
}
删除节点
public void delete(){
NodeList brands = document.getElementsByTagName("Brand");
for (int i = 0; i < brands.getLength(); i++) {
Node brand = brands.item(i);
Element eleBrand = (Element) brand;
if (eleBrand.getAttribute("name").equalsIgnoreCase("OPPO")){
eleBrand.getParentNode().removeChild(eleBrand);
}
}
this.saveXML("new.xml");
}
DOM4J1-6-1
获取整个xml文档
public void loaddocument(){
SAXReader saxReader = new SAXReader();
File url = new File("E:\javaWorkSpace\高级特效\Dom4j1.6.1\src\收藏信息.xml");
doc = saxReader.read(url);
}
显示所有信息
public void shouInfo(){
Element root = doc.getRootElement();
Iterator iterator = root.elementIterator();
while (iterator.hasNext()){
Element brandEle = (Element) iterator.next();
String brandStr = brandEle.attributevalue("name");
Iterator itType = brandEle.elementIterator();
while (itType.hasNext()){
Element typeEle = (Element) itType.next();
String typeStr = typeEle.attributevalue("name");
System.out.println("手机品牌"+brandStr+",型号:"+typeStr);
}
}
}
保存xml文件
public void savexml(String path){
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("gb2312");
XMLWriter writer = new XMLWriter(new FileWriter(path),format);
writer.write(doc);
writer.close();
}
添加节点
public void addPhoneInfo(){
Element root = doc.getRootElement();
//创建一个Brand节点
Element brandEle = root.addElement("Brand");
brandEle.addAttribute("name","三星");
//创建Type节点
Element TypeEle = brandEle.addElement("Type");
TypeEle.addAttribute("name","Note10");
this.savexml("new收藏.xml");
}
修改节点
public void updatePhoneInfo(){
Element root = doc.getRootElement();
Iterator itBrand = root.elementIterator();
while (itBrand.hasNext()){
Element brandEle = (Element) itBrand.next();
if (brandEle.attributevalue("name").equals("三星")){
brandEle.setAttributevalue("name","SUMSUNG");
}
}
this.savexml("new收藏.xml");
}
删除节点
public void deletePhoneInfo(){
Element root = doc.getRootElement();
Iterator itBrand = root.elementIterator();
while (itBrand.hasNext()){
Element brandEle = (Element) itBrand.next();
if (brandEle.attributevalue("name").equals("三星")){
brandEle.getParent().remove(brandEle);
}
}
this.savexml("new收藏.xml");
}
反射机制
反射:被视为动态语言的关键
反射机制:指在运行状态中,动态获取信息以及动态调用对象的方法的功能。
好处:
程序运行中、操作对象
解耦合,提高程序的可扩展性
应用场景:
动态创建、操作对象
框架内的拦截配置
动态性质:
运行时创建对象实例
运行时调用方法
运行时更改属性
常用API
| 类名 | 作用 |
|---|
| Class | 反射的核心类,获取类的属性、方法等内容信息 |
| Field | 定义类的属性,获取和设置属性的值 |
| Method | 定义类的方法、获取类中方法的信息、以及执行方式 |
| Constructor | 定义类的构造函数 |
| Field | 提供有关类或接口的单个字段,以及对它的动态访问权限 |
//运行时创建对象
//方式一: 使用newInstance() 创建 只能调用无参构造
Class student = Student.class;
Student s = (Student) student.newInstance();
System.out.println(s.toString());
//方式二: 先获取Constructor对象,然后使用newInstance() 创建
Class student1 = Student.class;
//获取Student中带有String和int参数的构造方法对象
Constructor c = student1.getConstructor(String.class,int.class);
Student s1 = (Student) c.newInstance("张三",18);
System.out.println(s1.toString());
| 方法名 | 说 明 |
|---|
| .getMethod(String name , Class[] params) | 返回此Class对象所表示的类的指定的public方法 |
| .Method[] getMethods() | 返回此Class对象所表示的类的所有public方法 |
| getDeclaredMethod(String name , Class[] prarms) | 返回此class对象所表示的类的指定的方法,与方法的访问级别无关 |
| getDeclaredMethod() | 返回此class对象所表示的类的全部方法,与方法的访问级别无关 |
//获取私密性方法
Student s = new Student();
Class stuclas = Student.class;
Method m = stuclas.getMethod("study", String.class);
m.invoke(s,"Java编程");
| 方法名 | 说 明 |
|---|
| .getXXX(obj) | 获取当前类型的值,该方法中Xxx对应8个基本数据类型. |
| .get(obj) | 获取指定对象上此属性的值 |
| .setXXX(obj , value) | 将obj对象的该属性设置成value值(此处的Xxx对应8个基本数据类型) |
| .set(obj , value) | 将obj对象的该属性设置成value值(针对引用类型赋值) |
| .setAccessible(true) | 对获取到的属性设置访问权限 |
//获取初始化属性,并开放权限
Student s = new Student();
//获取Student类的Class对象
Class student = Student.class;
//获取各个访问级别的属性
Field nameField = student.getDeclaredField("name");
//取消权限的检查
nameField.setAccessible(true);
//调用set方法设置新值
nameField.set(s,"张三");
//获取各个访问级别的属性
Field ageField = student.getDeclaredField("age");
//取消权限的检查
ageField.setAccessible(true);
//调用set方法设置新值
ageField.set(s,20);
System.out.println(s.toString());
| 方法名 | 说 明 |
|---|
| .newInstance(对象或类型.class ,长度 ) | 动态创建指定类型和长度的数组 |
| .get(arr , 下标) | 返回指定数组下标值 |
| .set(arr , 下标 , new 对象名(传参)) | 将制定数组下标设置新值 |
//动态创建数组
//动态创建Student类型的数组
Object arr = Array.newInstance(Student.class,10);
//存值
Array.set(arr,3,new Student("张三",18));
Array.set(arr,4,new Student("李四",20));
//取值
Student s1 = (Student) Array.get(arr,3);
Student s2 = (Student) Array.get(arr,4);
System.out.println(s1.toString());
System.out.println(s2.toString());
| 方法名 | 说 明 |
|---|
| getField(String name) | 返回此Class对象所表示的类的指定的public属性 |
| getField() | 返回此Class对象所表示的类的所有public属性 |
| getDeclaredField(String name) | 返回此class对象所表示的类的指定属性,与属性的访问级别无关 |
| getDeclaredFields() | 返回此Class对象所表示的类的全部属性,与属性的访问级别无关 |
//学员操作 综合练习
Pet p1 = new Pet();
Class pet = Pet.class;
//获取权限值
Field nameField = pet.getDeclaredField("name");
Field ageField = pet.getDeclaredField("age");
Field sexField = pet.getDeclaredField("sex");
Field loveField = pet.getDeclaredField("love");
nameField.setAccessible(true);
ageField.setAccessible(true);
sexField.setAccessible(true);
loveField.setAccessible(true);
nameField.set(p1,"葛霄");
ageField.set(p1,6);
sexField.set(p1,"妙妙");
loveField.set(p1,52.0);
Method m = pet.getMethod("eat",String.class);
System.out.println(p1.toString());
m.invoke(p1,"葛霄");
注解
简介:注解是java代码里的特殊标记,为java程序代码提供了一种形式化的方法、
注解以标签的形式存在于java代码中、注解的存在并不影响程序代码的编译和执行,
他只是用来生成其他文件或使我们在运行代码时知道 被运行代码的描述信息
| 作用: | |
|---|
| 编写文档 |
| 替代配置文件 |
| 编译检查 |
| 应用: | |
| 通过注解的方法进行数据库的连接 |
| 企业级Web框架开发通过大量注解配置、减少代码量 |
语法:
@Annotation(参数)
Annotation为注解类型
注解的参数可以没有,也可以有一个或多个
@Override
@SuppressWarnings(value="unused")
@MyTag(name="张三",age="18")
| 使用注解语法时,需要注意以下规范 | |
|---|
| 在将注解置于所有修饰符前 |
| 通常注解单独放一行 |
| 默认情况下,注解可用于修饰任何程序元素,包括类、方法和成员变量等 |
| 内建注解 | 说明 |
|---|
| @Override | 加上此注解,如果重写方法修饰不一样会自动在注解上报错 |
| @Deprecated | 过时注解,表示此方法或属性、类以过时,调用时会有下划线 |
| @SuppressWarnings(“all”) | 一般修饰整个类,抵制编译器黄色警告 all 为所有 |
| @SuppressWarnings("*") | * 说明 |
|---|
| deprecation | 使用了过时程序元素 |
| unchecked | 执行了未检查的转换 |
| unused | 有程序元素未被使用 |
| fallthrough | switch程序块直接通往下一种情况而没有break |
| path | 在类路径、源文件路径等中有不存在的路径 |
| serial | 在可序列化的类上缺少serialVersionUID定义 |
| finally | 任何finally字句不能正常完成 |
| all | 所有情况 |
如果@SuppressWarnings注解所声明的被禁止的警告个数只有一个时,则可不用大括号
@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked","fallthrough"})
| 元注解 | 说明 |
|---|
| @Target | 可设置注解类型 |
| @Retention | |
| @documented | |
| @Inherited | |
自定义注解:注解类型定义后,就可以用它来修饰程序中的类、接口、方法、成员变量等程序
只能返回基本数据类型 以及以上类型的数组、枚举、注解
//自定义注解
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnol {
String a();
}
//测试类
@MyAnnol(a="葛霄")
@SuppressWarnings("all")
public class Test {
public static void main(String[] args) throws Exception {
//获取本类所有注解
Annotation[] arr = Class.forName("读取注解.Test").getAnnotations();
for (Annotation a:arr){
System.out.println(a);
}
}
}