Java_05 常用類:註解反射,String,BigDecimal,Date,io,Serializable
阿新 • • 發佈:2021-01-01
目錄
註解
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();
}
}