Java_05 常用类:注解反射,String,BigDecimal,Date,io,Serializable
目录
注解
JDK1.5,可以被其他程序(如编译器)读取
格式:@注释名(参数值)
内置注解:
- @Override 重写;
- @Deprecated 不推荐使用,但可以使用,或者存在更好的方式;
- @SuppressWarnings("all") 镇压警告
元注解:负责注解其他注解
- @Target(value = ElementType.METHMOD),描述注解的范围,方法、类。。;
- @Retention(value = RetentionPolicy.RUNTIME) 表示注解在什么地方还有效,runtime>class>sources;
- @Documented 表示是否将我们的注解生成在Javadoc中;
- Inherited 子类可以继承父类的注解
自定义注解:
- @interface
反射
Reflection允许程序在执行期间借助Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法,加载完类之后,在堆内存的方法区中就产生可一个Class类型的对象,一个类只有一个Class类型对象,这个对象包含了类的全部结构,我们可以通过这个对象看到整个类的结构。
Class c = Class.forName("java.lang.String")
-
获取Class类的实例
-
若已知具体的类,可以通过类的class属性获取,该方法安全可靠,程序性能最高
Class clazz = Person.class;
-
已知某个类的实例,调用该实例的getClass()方法获取Class对象
Class clazz = person.getClass();
-
已知一个类的全类名,且该类在类的路径下,可以通过Class类的静态方法forName()获取,可能抛出一个ClassNotFoundException
Class clazz = Class.forName("java.lang.String")
package com.alpari; public class Demo { public static void main(String[] args) throws ClassNotFoundException { Person person = new Person(); // 1.通过对象 Class c1 = person.getClass(); System.out.println(c1.hashCode()); // 2.forName Class c2 = Class.forName("com.alpari.Person"); System.out.println(c2.hashCode()); // 3.通过类名 Class c3 = Person.class; System.out.println(c3.hashCode()); } } class Person{ public String name; public Person() { } public Person(String name) { this.name = name; } } // 输出:一个类只有一个Class类型的对象 1163157884 1163157884 1163157884
-
-
类的加载
-
加载:将class字节码文件加载到内存中,将这些静态数据转换成方法区的运行时数据结构,生成java.lang.Class对象
-
链接
-
初始化:
() 方法; 类的主动引用(一定初始化):
- 虚拟机启动初始化main方法
- new对象
- 反射调用
- 调用类的静态成员(除了final常量)和静态方法
- 初始化一个类,如果其父类没有初始化,则先初始化父类
类的被动引用(不会初始化):
- 当访问一个静态域,只有真正声明这个域的类才会被初始化,如:当通过子类引用 父类的静态变量,不会导致子类初始化
- 通过数组定义类的引用,不会出大此类的初始化
- 引用常量不会(常量在链接阶段就存入调入类的常量池中了)
-
反射调用
package com.alpari;
import java.lang.reflect.Field;
public class Demo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
// forName
Class c = Class.forName("com.alpari.Person");
// 获得类的名字
System.out.println(c.getName()); // com.alpari.Person
System.out.println(c.getSimpleName()); // Person
// 获得类的属性getFields()只能获取public属性
Field[] fs1 = c.getFields();
for (Field f1:fs1) {
System.out.println(f1); // public java.lang.String com.alpari.Person.name
}
Field[] fs = c.getDeclaredFields();
for (Field f: fs) {
System.out.println(f); // public java.lang.String com.alpari.Person.name
// private int com.alpari.Person.age
}
// 获得指定属性的值
Field age = c.getDeclaredField("age");
System.out.println(age); // private int com.alpari.Person.age
// 获得类的方法 c.getMethods()是获得本类及其父类全部的public方法
Method[] ms = c.getDeclaredMethods(); // 获得本类的所有方法
for (Method m:ms) {
System.out.println(m);
}
/*public java.lang.String com.alpari.Person.getName()
public void com.alpari.Person.setName(java.lang.String)
public int com.alpari.Person.getAge()
public void com.alpari.Person.setAge(int)*/
// 获得类的构造方法
Constructor[] ds = c.getDeclaredConstructors();
for (Constructor d:ds) {
System.out.println(d); //com.alpari.Person()
}
}
}
class Person{
public String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
创建对象执行操作
package com.alpari;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Demo {
public static void main(String[] args) throws Exception, InstantiationException, NoSuchMethodException, InvocationTargetException {
// forName
Class c = Class.forName("com.alpari.Person");
// 构造一个对象
Person p = (Person) c.newInstance(); // 本质调用类的无参构造器
// 通过反射调用普通方法
Method setName = c.getDeclaredMethod("setName", String.class);
// invoke 激活
setName.invoke(p,"w");
System.out.println(p.getName()); // w
// 通过反射调用普通方法
Field name = c.getDeclaredField("name");
// name.set(p,"hee");
// System.out.println(p.getName());
// Exception in thread "main" java.lang.IllegalAccessException: Class com.alpari.Demo can not access a member of class com.alpari.Person with modifiers "private"
// 不能直接操作私有属性,我们需要关闭安全检查
name.setAccessible(true);
name.set(p,"hee");
System.out.println(p.getName()); // hee
}
}
class Person{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
常用类
String
字符串是常量,创建之后不可改变,字符串存于常量池中
package com.alpari;
public class Demo {
public static void main(String[] args) {
String name = "hello"; // 在常量池中开辟一块空间存了hello
name += "world"; // 会在常量池中另外开辟一个空间存world,然后再开辟一块空间来存helloworld,这样之前的hello和world就成为垃圾空间
System.out.println(name); // helloworld
String name2 = "aaa";
String name3 = "aaa";
String name4 = new String("aaa"); // 创建2个对象,相当于在堆内存中存了一个对象,一个存在了常量池
String name5 = new String("aaa");
System.out.println(name2 == name3); // true
System.out.println(name2 == name4); // false
System.out.println(name4 == name5); // false
System.out.println(name4.equals(name5)); //true
// == 默认对比的是内存地址,字符串对比要用equals,equals本身默认对比内存地址,但是被String类重写了
}
}
常用方法
package com.alpari;
import java.util.Arrays;
public class Demo {
public static void main(String[] args) {
String name = "hello"; // 在常量池中存了hello
name += "world"; // 会在常量池中另外开辟一个空间存world,然后再开辟一块空间来存helloworld,这样之前的hello和world就成为垃圾空间
// 字符串常用方法
String content = "java is the best";
// 1.length() 返回字符串长度
System.out.println(content.length()); // 16
// 2.charAt(int index) 返回某个位置的字符
System.out.println(content.charAt(content.length()-1)); // t
// 3.contains(String str) 判断是否包含某个字符,有返回true
System.out.println(content.contains("t")); // true
// 4.toCharArray() 返回字符串对应的数组
System.out.println(Arrays.toString(content.toCharArray())); // [j, a, v, a, , i, s, , t, h, e, , b, e, s, t]
// 5.indexOf() 返回字符串首次出现的位置
System.out.println(content.indexOf("t")); // 8
System.out.println(content.indexOf("t", 9)); // 15
// 6.lastIndexOf() 返回字符串最后一次出现的位置
System.out.println(content.lastIndexOf("t")); // 15
// 7.trim() 去掉字符串前后的空格
// 8.toUpperCase() 小写转大写 // toLowerCase()
// 9.endWith(str) 判断是否已str结尾 // startWith(str) 判断是否已str开头
// 10.replace(char old, char new) 替换
System.out.println(content.replace("java","c++")); // c++ is the best
// 11.split 对字符串拆分
String[] s = content.split(" ");
for (String s1 : s) {
System.out.println(s1);
}
// 12.substring(startIndex, endIndex);字符串截取,end不写则代表截取到最后,左闭右开[ )
}
}
StringBuffer,StringBuilder
StringBuffer可变长字符串,线程安全
StringBilder可变长字符串,线程不安全,效率最高
package com.alpari;
import java.util.Arrays;
public class Demo {
public static void main(String[] args) {
StringBuilder str = new StringBuilder();
// 1.append
str.append("hello");
System.out.println(str); // hello
str.append("world");
System.out.println(str.toString()); // helloworld
// 2.reverse 反转
// 3.insert(int offset, 任意类型) 在某个index后插入字符串
// 4.toString() 返回String类对象
// String类转为StringBuilder类
String s = "c++";
StringBuilder sb = new StringBuilder(s);
System.out.println(sb);
// StringBulider转为String
System.out.println(sb.toString());
}
}
BigDecimal
package com.alpari;
import java.math.BigDecimal;
public class Demo {
public static void main(String[] args) {
double d1 = 1.0;
double d2 = 0.9;
System.out.println(d1-d2); // 0.09999999999999998
BigDecimal bdl = new BigDecimal("1.0");
BigDecimal bd2 = new BigDecimal("0.9");
// 加法:bdl.add(bd2)
// 减法:bdl.subtract(bd2)
System.out.println(bdl.subtract(bd2)); // 0.1
// 乘法:bdl.multiply(bd2)
// 除法:bdl.divide(bd2) 除不尽的 2是保留小数位数,ROUND_HALF_UP 四舍五入
BigDecimal divide = new BigDecimal("10").divide(new BigDecimal("3"), 2, BigDecimal.ROUND_HALF_UP);
System.out.println(divide); // 3.33
}
}
Date
package com.alpari;
import java.util.Calendar;
import java.util.Date;
public class Demo {
public static void main(String[] args) {
// 打印当前时间
System.out.println(new Date()); // Fri Jan 01 14:14:38 CST 2021
// SimpleDateFormat 格式化日期
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String s = sf.format(new Date());
System.out.println(s); // 2021-01-01 14:26:23
// 创建Calendar对象
Calendar c = Calendar.getInstance();
System.out.println(c.getTimeInMillis());
// 获取时间信息
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH); // 月是从0开始算
int day = c.get(Calendar.DAY_OF_MONTH);
int minute = c.get(Calendar.MINUTE);
int second = c.get(Calendar.SECOND);
}
}
io流
Java程序进行数据传输的管道
file
package com.alpari;
import java.io.File;
public class Demo {
public static void main(String[] args) throws Exception {
File file = new File("C:\\Users\\49254\\Desktop\\typora\\text.txt");
boolean newFile = file.createNewFile(); // 创建成功返回true,否则false,不能重复创建
// 路径必须存在,否则异常;如果没有指明创建文件的路径,默认为该路径下创建
file.mkdir(); // 创建单层文件夹,成功为true
file.mkdirs(); // 创建多层文件夹
file.delete(); // 删除的文件夹下不能有文件夹或文件
file.renameTo(new File("b")); // 同路径下修改文件夹名或文件名a改为b;不同路径为剪切粘贴
file.isDirectory(); // 判断a是否为文件夹(目录)
file.isFile(); // 判断是否为文件
file.exists(); // 判断是否存在
file.canRead(); // 判断文件是否可读
file.canWrite(); // 判断是否可写
file.isHidden(); // 判断是否隐藏
file.getAbsolutePath(); // 获取绝对路径
file.getPath(); // 相对路径
file.getName(); // 获取名字
file.length(); // 文件长度,文件夹为0
file.lastModified(); // 最后一次修改时间,毫秒值
file.list(); // 文件夹列表
}
}
package com.alpari;
/**
* 把C:\Users\49254\Desktop\typora下所有.png文件找出来
*/
import java.io.File;
public class Demo {
public static void main(String[] args) throws Exception {
File file = new File("C:\\Users\\49254\\Desktop\\typora");
// 得到该路径下所有文件名称
String[] list = file.list();
// 判断每个文件名称是否以 .png结尾
// 得到该文件夹下所有的文件对象
File[] files = file.listFiles();
for (File file1 : files) {
if (file1.getName().endsWith(".png")) {
String path = file1.getAbsolutePath();
System.out.println(path); // C:\Users\49254\Desktop\typora\text.png
}
}
}
}
package com.alpari;
import java.io.FileOutputStream;
public class Demo {
public static void main(String[] args) throws Exception {
print(new File("c:"+File.separator));
}
/**
* 获得C盘下的所有文件目录及文件子目录里面的所有目录,递归
*/
public static void print(File file){
if (file.isDirectory()) { //先判断文件是否是目录
File[] files = file.listFiles();//列出所有子目录,及文件
if (files != null) { //如果子目录不为空
for (int i = 0; i < files.length; i++) {//循环子目录
print(files[i]); //递归调用 传递子目录
}
}
}
System.out.println(file);//输出完整路径
}
/**
* 获取目录下的所有直接目录
*/
private void method3() {
File file = new File("c:"+File.separator);
if (file.isDirectory()) {
File[] listFiles = file.listFiles();// 获取目录下的所有直接目录
for (int i = 0; i < listFiles.length; i++) {
System.out.println(listFiles[i]); //调用toString方法
}
}
}
/**
* 取得文件 信息
*/
public void method2() {
File file = new File("d:"+File.separator+"123.png");
if (file.exists()) {
System.out.println(file.isFile()); //是否是文件
System.out.println(file.isDirectory()); //是否是目录
System.out.println(file.length());//文件的字节大小
//文件的字节大小(m)--new BigDecimal((double)file.length()/1024/1024).divide(new BigDecimal(1),2,BigDecimal.ROUND_HALF_UP)
//获取文件最后修改日期,file.lastModified(),返回的是long类型
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(file.lastModified())));
}
}
/**
*
* 创建文件目录,即父路径
*/
public void method1() throws Exception{
File file=new File("d:"+File.separator+"demo"+File.separator+"hello"+File.separator+"java"+File.separator+"demo.txt");//多层目录文件
//根据file.getParentFile()取得文件父目录信息,然后判断是否存在
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();// 创建多层文件父目录
file.createNewFile(); //创建文件
}
}
/**
* 创建文件,在java.io操作会出现延迟情况,因为现在的问题是Java虚拟机间接调动系统的文件处理函数进行文件处理。
* @throws Exception
*/
public void method() throws Exception {
File file = new File("d:\\demo.txt");
if (file.exists()) {//文件存在返回true 否则返回false
file.delete();// 删除文件
}else { //文件不存在
file.createNewFile(); //创建文件
}
}
}
InputStream
package com.alpari;
import java.io.FileInputStream;
public class Demo {
public static void main(String[] args) throws Exception {
// 1.创建FileInputStream
FileInputStream fis = new FileInputStream("DC:\\Users\\49254\\Desktop\\typora\\aa.txt");
// 2.读取
byte[] bytes = new byte[1024];
int count = 0;
while ((count = fis.read(bytes))!=-1){
System.out.println(new String(bytes, 0, count));
}
// 3.关闭
fis.close();
}
}
package com.alpari;
import java.io.FileOutputStream;
public class Demo {
public static void main(String[] args) throws Exception {
File file = new File("d:/readme.txt");//定义要输入文件的路径
InputStream input = new FileInputStream(file);
byte [] data = new byte[1024];
/*int read = input.read(data);
System.out.println(read);
input.close();
System.out.println(new String(data,0,read));*/
int foot=0;// 表示字节数组的脚标
int temp=0;// 表示接收每次读取的字节数据
//1.temp=input.read() 2.(temp=input.read())!=-1
while ((temp=input.read())!=-1) {
data[foot++]=(byte)temp;
}
input.close();
System.out.println(new String(data,0,foot));
}
}
OutputStream
package com.alpari;
import java.io.FileOutputStream;
public class Demo {
public static void main(String[] args) throws Exception {
// 1.创建FileInputStream new FileOutputStream("d:\\bb.txt", true) true是追加文件,无则是创建或者覆盖
FileOutputStream fileOutputStream = new FileOutputStream("d:\\bb.txt");
// 2.写入
String s = "hello";
fileOutputStream.write(s.getBytes());
// 3.关闭
fileOutputStream.close();
}
}
package com.alpari;
import java.io.FileOutputStream;
public class Demo {
public static void main(String[] args) throws Exception {
File file = new File("d:"+File.separator+"demo"+File.separator+"hello.txt");
if (!file.getParentFile().exists()) {//判断文件路径是否存在
file.mkdirs(); //创建文件路径
}
//FileOutputStream 在构造方法中使用true 进行文件内容追加,无true是创建或覆盖已有文件
OutputStream out = new FileOutputStream(file,true);//创建一个字节输出流,利用子类实例化
String str="恭喜\r\n";// \r\n换行
byte[] bytes=str.getBytes(); //讲字符串转化为byte数组
out.write(bytes,4,6);//讲byte数组的部分内容写入到文件中,6是长度
out.close();//关闭输出流,释放系统资源
}
/**
* byte 数组写入方式
* @throws Exception
*/
public static void method() throws Exception{
File file = new File("d:"+File.separator+"demo"+File.separator+"hello.txt");//1.定义要输出文件的路径
if (!file.getParentFile().exists()) {//判断文件路径是否存在
file.mkdirs(); //创建文件路径
}
//FileOutputStream 在构造方法中使用true 进行文件内容追加。
OutputStream out = new FileOutputStream(file,true);//2.创建一个字节输出流,利用子类进行实例化
String str="早上没吃饭,有点饿了";
byte[] bytes=str.getBytes(); //3.将字符串转化为byte字节数组
out.write(bytes); //将byte数组的内容写入到文件中,即将内容输出
out.close();//4.关闭输出流,释放系统资源
}
}
Writer,Reader
/* Writer---- 字符输出流
* Reader---- 字符输入流
* 字节流与字符流字区别是:字节流直接与终端进行数据交互,而字符流需要将数据经过缓冲区后处理,有中文用字符流,无中文用字节流。
*/
public class MainClassWriterAndReader {
public static void main(String[] args) throws Exception {
/* File file = new File("d:/abc.txt");
Writer wr = new FileWriter(file,true);//实例化对象
wr.write("s");//输出字符串数据
wr.flush();//清空 缓存区内容,强制清空缓冲区
wr.close();//关闭 */
/* File file = new File("d:/abc.txt");
Reader readr = new FileReader(file);
char [] c=new char[1024];
int read = readr.read(c);
readr.close();
System.out.println(new String(c,0,read));
*/
// 输出流转换
/* File file = new File("d:/abc.txt");
OutputStream out = new FileOutputStream(file,true); //字节流
Writer wr = new OutputStreamWriter(out);
wr.write("asjkdfasdhjkasdhfjksadhfjksdhf");
wr.flush();*/
/* File file = new File("d:/abc.txt");
InputStream input=new FileInputStream(file);
Reader r=new InputStreamReader(input);
char [] c=new char[1024];
int read = r.read(c);
r.close();
System.out.println(new String(c,0,read));*/
// 文件复制操作 DOS系统的文件拷贝
/* long i = System.currentTimeMillis();
File file = new File("D:\\dog.jpg");
File file2 = new File("D:\\dog2.jpg");
InputStream input = new FileInputStream(file);
OutputStream out = new FileOutputStream(file2);
int temp=0; // 保存每次读取的个数
byte data[]=new byte[1024]; // 每次读取1024字节
while((temp=input.read(data))!=-1){ // 将每次读取进来的数据保存在字节数组里,并且返回读取的个数
out.write(data, 0, temp); // 输出数组
}
input.close();
out.close();
System.out.println("时间过了"+(System.currentTimeMillis()-i));*/
// 中文乱码
/* File file = new File("d:/abc.txt");
OutputStream out = new FileOutputStream(file);
out.write("世界那么美,我想去看看".getBytes("ISO8859-1"));
out.close();
InputStream input = new FileInputStream(file);
int temp=0;
String n="hahaha";
byte[] bytes = n.getBytes("ISO8859-1");
byte data[]=new byte[1024];
temp=input.read(data);
byte[] a= new String (data).getBytes("ISO8859-1");
// byte[] b= new String (a).getBytes("GBK");
String s=new String (a,"gbk");
// new String (new String (new String (data,0,temp).getBytes("iso8859-1")).getBytes("GBK"));
System.out.println(s);*/
// 文件合并读取
File file = new File("D:\\abc.txt");
File file2 = new File("D:\\readme.txt");
InputStream in=new FileInputStream(file);
InputStream in2=new FileInputStream(file2);
//内存输出流
ByteArrayOutputStream out = new ByteArrayOutputStream();
int temp=0;
while ((temp=in.read())!=-1) {
out.write(temp); //把文件的字节内容保存在内存输出流中
}
while((temp=in2.read())!=-1){
out.write(temp); //把文件的字节内容保存在内存输出流中
}
byte [] bytes=out.toByteArray(); //取出内存输出流的全部数据
out.close();
in.close();
in2.close();
System.out.println(new String(bytes));
}
}
Serializable
// Serializable --- 序列化对象的核心操作,没有任何抽象方法,因为他是一个标识接口。(clone)
public class User implements Serializable{
private static final long serialVersionUID = 1L;
private String name;
private transient String sex; // transient 关键字不保存
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "User [name=" + name + ", sex=" + sex + "]";
}
public User(String name, String sex) {
super();
this.name = name;
this.sex = sex;
}
public User() {
super();
}
}
public class MainClass {
public static void main(String[] args) throws Exception, IOException {
/*method();
method1();*/
}
/**
* 取出属性文件的内容
*/
public static void method3() throws Exception{
method2();
InputStream in = new FileInputStream( new File("d:\\demo.properties"));
Properties ps=new Properties();
ps.load(in);
User u= new User();
u.setAge(Integer.parseInt(ps.getProperty("age")));
u.setNumber(Integer.parseInt(ps.getProperty("number")));
u.setName(ps.getProperty("name"));
u.setSex(ps.getProperty("sex"));
System.out.println(u);
}
/**
* 创建属性文件及往里面写入内容
*/
public static void method2() throws Exception{
User u=new User("www","男");
OutputStream out = new FileOutputStream( new File("d:\\demo.properties"));
// 在内存中创建一个属性文件对象
Properties ps=new Properties();
ps.setProperty("name", u.getName());
ps.setProperty("age", String.valueOf(u.getAge()));
ps.setProperty("sex", u.getSex());
ps.setProperty("number", String.valueOf(u.getNumber()));
ps.store(out, "");
}
/**
* 序列化对象
* @throws IOException
* @throws FileNotFoundException
*/
public static void method() throws FileNotFoundException, IOException{
User u = new User("张三", "男");
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(new File("d:\\user.ser")));
out.writeObject(u);
out.close();
}
/**
* @throws IOException
* @throws FileNotFoundException
* @throws ClassNotFoundException
* 反序列化对象
*/
public static void method1() throws Exception{
ObjectInputStream in = new ObjectInputStream(new FileInputStream(new File("d:\\user.ser")));
Object object = in.readObject();
User u=(User) object;
System.out.println(u);
in.close();
}
}