第十章 Java常用类库
10.1 StringBuffer类
String类最大的问题就是String类不可改变。这时候就可以用StringBuffer类中的append()方法进行数据的连接。
观察 StringBuffer类
public class TestDemo {
public static void main(String[] args) throws Exception {
StringBuffer buf=new StringBuffer();
buf.append("Hello").append("MLDN").append("!!");
change(buf);
System.out.println(buf);
}
public static void change(StringBuffer temp){
temp.append("\n").append("朱小东好帅");
}
}
取得Char Sequence接口实例化对象
String和String Buff类的对象都可以利用自动向上转型的操作Char Sequence接口实例化。
取得CharSequence接口实例化
public class TestDemo {
public static void main(String[] args) throws Exception {
CharSequence seq="朱小东好帅";
System.out.println(seq);
}
}
String与StrungBuffer不能直接进行转换,需要进行一下进行操作。
原则一:将String转换为StringBuffer类对象
方式一:利用StringBuffer类的构造方法
StringBuffer buf=new StringBuffer("朱夏东");
方式二:利用StringBuffer类中的append()方法;
StringBuffer buf=new StringBuffer();
buf.append("朱小东");
原则二:将StringBuffer类变为String
方式一:利用toString()方法
StringBuffer buf=new StringBuffer("zhuxiaod");
String str=buf.toString();
方式二:利用String类的构造方法实现转换:
StringBuffer buf=new StringBuffer("zhuxiaod");
String str=new String();
常用的操作方法:
contentEquals():实现字符串的比较;
**append()😗*数据追加操作
**reverse()😗*字符串反转操作
**insert():**在指定位置增加数据
**delete()😗*删除部分数据
public class TestDemo {
public static void main(String[] args) throws Exception {
StringBuffer buf=new StringBuffer("zhuxiaod");
System.out.println(buf.reverse());
buf.insert(0,"zhu");
System.out.println(buf);
System.out.println(buf.delete(1,4));
}
}
请解释String类、StringBuffer类和StringBuilder类的区别。
- String类的内容一旦声明则不可改变,而StringBuffer类与StringBuilder类声明的内容可以改变。
- StringBuffer类中提供的方法都是同步方法,属于安全的线程操作;而StringBuilder类中的方法都属于异步方法,属于非线程安全的操作。
10.2 Runtime类
作用:可以启动新的进程或进行相关运行时环境的操作。(构造方法已经被私有化了。
常用方法:
getRuntime():取得Runtime类实例化对象
maxMemory:返回最大可用内存大小
totalMeMory:返回所有可以内存大小
freeMemory:返回所有空余内存空间
gc():执行垃圾回收操作
IOException:创建新的进程
public class TestDemo {
public static void main(String[] args) throws Exception {
Runtime run=Runtime.getRuntime();
System.out.println("MAX"+run.maxMemory());
System.out.println("T"+run.totalMemory());
System.out.println("F"+run.freeMemory());
run.gc();
System.out.println("F="+run.freeMemory());
}
}
请解释什么叫GC,如何处理?
- GC垃圾收集器,指的是释放无用的内存空间;
- GC会由系统不定期进行自动回收,或者调用Runtime类中的gc()方法手工回收。
10.3 System类
常用操作:
arraycopy():数组复制
currentTimeMillis():取得当前的日期时间,以long型的数据返回。
gc():垃圾回收
请统计出某项操作的执行时间
单位毫秒
public class TestDemo {
public static void main(String[] args) throws Exception {
long start=System.currentTimeMillis();
String str="";
for (int x=0;x<30000;x++){
str+=x;
}
long end=System.currentTimeMillis();
System.out.println("本次操作花费的时间:"+(end-start));
}
}
对象回收操作
class Human {
public Human(){
System.out.println("祸害诞生了");
}
@Override
protected void finalize() throws Throwable{
System.out.println("活了100年");
throw new Exception("此处即使抛出异常对象也不会产生影响");
}
}
public class TestDemo {
public static void main(String[] args) throws Exception {
Human men=new Human();
men=null;
System.gc();
}
}
请解释final、finally、finally、finalize的区别。
- final表示终结器,用于不能被继承的父类,不能被覆写的方法、常量;
- finally是异常处理的出口;
- fialize()是Object类定义的一个方法,用于执行对象回收前的收尾操作。即使出现了异常,也不会产生中断异常处理。
10.4 对象克隆
public Object clone()throws CloneNotSupportedException{
return super.clone();
}
定义类时实现了Cloneable接口,同时在Book类中覆写了clone()方法。主类中首先产生一个新的实例化对象A,然后利用A对象的内容克隆出一个新的B对象,用于两个对象占据不同的堆内存空间,彼此不相互影响。
10.5 数字操作类
10.5.1 Math类
Math类就是一个专门进行数字计算的操作类,它提供了一系列数学计算方法。
System.out.println(Math.round(15.6));//四舍五入
利用BigDecimal大数字操作类完成保留小数位
public class TestDemo {
public static void main(String[] args) throws Exception {
System.out.println(round(15.662336,2));
}
public static double round(double num,int scale){
return Math.round(num*Math.pow(10.0,scale))/Math.pow(10.0,scale);
}
}
10.5.2 Randdom类
专门产生随机类数的操作类
Random():创建一个新的Random实例
Random(long seed):创建一个新的Random实例并设置一个种子数。
nextInt(int bound):产生一个不大于指定边界的随机整数。
实现36选7程序
public class TestDemo {
public static void main(String[] args) throws Exception {
Random rand=new Random();
int data[]=new int[7];
int foot=0;
while (foot<7){
int t=rand.nextInt(37);
if (!isRepeat(data,t)){
data[foot++]=t;
}
}
java.util.Arrays.sort(data);
for (int x=0;x<data.length;x++){
System.out.println(data[x]+"、");
}
}
public static boolean isRepeat(int temp[],int num){
if (num==0){
return true;
}
for (int x=0;x<temp.length;x++){
if (temp[x]==num){
return true;
}
}
return false;
}
}
10.5.3 大数字操作类
BigInteger和BigDecimal。
10.6 日期处理类
10.6.1 Data类
Data():实例化Data类对象;
Data():将数字变为Data类对象,long为日期时间数据。
getTime():将当前日期时间变为long型;
取得当前时间
public class TestDemo {
public static void main(String[] args) throws Exception {
Date data=new Date();
System.out.println(data);
}
}
Date与long间的转换
public class TestDemo {
public static void main(String[] args) throws Exception {
long cur=System.currentTimeMillis();
Date data=new Date(cur);
System.out.println(data);
System.out.println(data.getTime());
}
}
10.6.2 日期格式化:SimpleDataFormat
SimpleDataFormat:传入日期时间标记实例化对象。
format:将日期格式转化为字符串数据。
ParseException:将字符串格式转化为日期数据。
yyyy:年、MM:月、日:dd、HH:时、分:mm、秒:ss、毫秒:SSS
将日期格式化显示
public class TestDemo {
public static void main(String[] args) throws Exception {
Date date=new Date() ;
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM--dd HH:mm:ss.SSS");
String str=sdf.format(date);
System.out.println(str);
}
}
字符串转换为日期
public class TestDemo {
public static void main(String[] args) throws Exception {
String str="2005-07-2707:15:22.111";
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM--dd HH:mm:ss.SSS");
Date date=sdf.parse(str);
System.out.println(date);
}
}
数据类型的转换操作
- Date与String类之间的转换依靠SimpleDateFormat
- String与基本类型之间的转换依靠包装类与String.value()方法。
- long与Date转换依靠Date类提供的构造以及getTime()方法。
10.6.3 Calendar类
正常操作
public class TestDemo {
public static void main(String[] args) throws Exception {
Calendar cal=Calendar.getInstance();
StringBuffer buf=new StringBuffer();
buf.append(cal.get(Calendar.YEAR)).append("-"); //取得年数据
buf.append(cal.get(Calendar.MONDAY)+1).append("-"); //取得月数据,从零开始
buf.append(cal.get(Calendar.DAY_OF_MONTH)).append(" ");//取得天数据
buf.append(cal.get(Calendar.HOUR_OF_DAY)).append(":");//取得小时数据
buf.append(cal.get(Calendar.MINUTE)).append(":");//取得分钟数据
buf.append(cal.get(Calendar.SECOND)); //取得秒数据
System.out.println(buf);
}
}
getInstance():根据默认的时区实例化对象。
after():判断一个日期是否在指定日期之后。
before():判断一个日期是否在指定日期之前。
get():返回给定日历字段的值。
10.7 比较器
10.7.1 Array类
一个定义在java.util包中专门进行数组的操作类,在这个类中定义了所有与数组有关的基本操作:二分查找、相等判断,数组填充。
equals():判断两个数组是否相等,此方法可以被重载多次,可以判断各种数据类型的数组。
fill():将指定内容填充到数组中,此方法被重载多次,可以填充各种类型的数组。
sort():数组排序,此方法被重载多次,可以填充各种类型的数组进行排序。
binarySearch():对排序后的数组进行检索,此方法被重载多次,可以对各种类型的数组进行检索。
toString():输出数组信息,此方法被重载多次,可以输出各种数据类型的数组。
实现二分法查找
public class TestDemo {
public static void main(String[] args) throws Exception {
int data[]=new int[]{1,5,6,7,43,7,5,3,32};
java.util.Arrays.sort(data);
System.out.println(Arrays.binarySearch(data,7));
//输出排序后的索引位置
}
}
数组相等比较
public class TestDemo {
public static void main(String[] args) throws Exception {
int data[]=new int[]{1,5,6};
int dataA[]=new int[]{1,5,6};
System.out.println(Arrays.equals(data,dataA));//比较数组是否相等
}
}
数组填充
public class TestDemo {
public static void main(String[] args) throws Exception {
int data[]=new int[10];
Arrays.fill(data,3);
System.out.println(Arrays.toString(data));//将数组变为字符串输出
}
}
10.7.2 比较器:Comparable
要想使用sort()方法进行排序,就必须有一个前提:对象所在的类一定要实现Comparable接口。
public class Book implements Comparable<Book>{
private String title;
private double price;
public Book(String title,double price){
this.title=title;
this.price=price;
}
@Override
public String toString(){
return "书名"+this.title+",价格"+this.price;
}
public int compareTo(Book o){
if (this.price>o.price){
return 1;
}else if (this.price<o.price){
return -1;
}else {
return 0;
}
}
}
public class TestDemo {
public static void main(String[] args) throws Exception {
Book books[]=new Book[]{
new Book("Java开发实战",12),
new Book("Jav开发实战",13),
new Book("Ja开发实战",1),
new Book("J开发实战",18),
};
Arrays.sort(books);//对象排序表
System.out.println(Arrays.toString(books));
}
}
10.7.3 数据结构–BinaryTree、
树是一种比链表更为复杂的概念应用,本质是一个动态数组。
实现二叉树
public class Book implements Comparable<Book>{
private String title;
private double price;
public Book(String title,double price){
this.title=title;
this.price=price;
}
@Override
public String toString(){
return "书名"+this.title+",价格"+this.price+"\n";
}
public int compareTo(Book o){
if (this.price>o.price){
return 1;
}else if (this.price<o.price){
return -1;
}else {
return 0;
}
}
}
class BinaryTree {
private class Node{
private Comparable data;
private Node left; //
private Node right;
public Node(Comparable data){
this.data=data;
}
@SuppressWarnings("unchecked")
public void addNode(Node newNode){
if (this.data.compareTo(newNode.data)>0){
if (this.left==null){
this.left=newNode;
}else {
this.left.addNode(newNode);
}
}else {
if (this.right==null){
this.right=newNode;
}else {
this.right.addNode(newNode);
}
}
}
public void toArrayNode(){
if (this.left!=null){
this.left.toArrayNode();
}
BinaryTree.this.retData[BinaryTree.this.foot++]=this.data;
if (this.right!=null){
this.right.toArrayNode();
}
}
}
private Node root;
private int count;
private Object[] retData;
private int foot;
public void add(Object obj){
Comparable com=(Comparable) obj;
Node newNode=new Node(com);
if (this.root==null){
this.root=newNode;
}else {
this.root.addNode(newNode);
}
this.count++;
}
public Object[] toArray(){
if (this.root==null){
return null;
}
this.foot=0;
this.retData=new Object[this.count];
this.root.toArrayNode();
return this.retData;
}
}
public class TestDemo {
public static void main(String[] args) throws Exception {
BinaryTree bt=new BinaryTree();
bt.add(new Book("Java开发实战",12));
bt.add(new Book("Jav开发实战",13));
bt.add(new Book("Ja开发实战",1));
bt.add(new Book("J开发实战",18));
Object obj[]=bt.toArray();
System.out.println(Arrays.toString(obj));
}
}
10.7.4 挽救的比较器:Comparator
该接口提供了一个compare()方法,此方法的返回3种结果:1(>0)、-1(<0)、0(=0).
Comparable和Comparator的区别
- 如果对象数组要进行排序就必须设置排序规则,可以使用Comparable或Comparator接口实现。
- java.lang.Comparable是在一个类定义时实现好的接口,这样本类的对象数组就可以进行排序,在Comparable接口下定义了一个public int compareTo()方法;
- java.util.Comparator是专门定义一个指定类的比较规则,属于挽救的比较操作,里面有两个方法:public int compare()、public boolean equals().
10.7.5 Comparable与Comparator的区别
- 如果对象数组要进行排序就必须设置排序规则,可以使用Comparable或Comparator接口实现
- java.lang.Comparable是在一个类定义时实现好的接口,这样本类的对象数组就可以进行排序,在Comparable接口下定义了一个public int compareTo()方法;
- java.util.Comparator是专门定义一个指定类的比较规则,属于挽救的比较操作,里面有两个方法:public int compare()、public boolean equals().
10.8 正则表达式
10.8.1 正则标记
正则表达式在本质上是一种字符串操作的语法规则,利用此语法法规可以更加灵活地实现字符串的匹配,拆分、替换等操作。
实现字符串判断
public class TestDemo {
public static void main(String[] args) throws Exception {
String str="123";
System.out.println(str.matches("\\d+"));
}
}
正则标记
- Pattern类:主要定义要使用的表达式对象。
- Matcher类:用于进行正则标记与指定内容的匹配操作。
常用标记
(1)单个字符
- 字符:表示由一位字符组成
- \:表示转义字符“\”;
- \t:表示一个"\t"符号;
- \n:匹配换行(\n)符号;
(2)字符集
- [abc];表示可能是字符a、字符b、字符c中的任意一位;
- [^abc];表示不是字符a、b、c中的任意一位;
- [a-z];表示所有的小写字母;
- [a-zA-Z];表示任意的一位字母,不区分大小写;
- [0-9];表示任意的一位数字;
(3)简化的字符集表达式
- :;表示任意的一位字符
- \d:等价与“[0-9]",属于简化写法
- \D:等价于"[[^0-9]]",属于简化写法
- \s:表示任意的空白字符
- \S:表示任意的非空字符
- \w:等价于"[a-zA-Z_0-9]",表示任意的字母、数字、_组成
- \W;等价于"[^^a-zA-Z_0-9]",表示不是由任意的字母、数字、_组成;
(4)边界匹配
- ^;正则的开始
- $;正则的结束
(5)数量表达
- 正则?;表示此正则可以出现0次或1次;
- 正则+:表示此正则可以出现1次或1次以上;
- 正则*:表示此正则可以出现0次、1次或多次;
- 正则{n}:表示此正则正好出现n次;
- 正则{n,}:表示此正则出现n次以上;
- 正则{n,m};表示此正则出现n~m次;
(6)逻辑运算
- 正则1正则2:正则1判断完成后继续判断正则2;
- 正则1|正则2;正则1或者是正则2有一组满足即可;
- (正则):将多个正则作为一组,可以为这一组单独设置出现的次数。
10.8.3 String类对正则的支持
String类与正则有关的5个操作方法(字符串替换、拆分、验证操作),其中验证最重要。
public boolean match(String regex):正则验证,使用指定的字符串判断其是否符合给出的正则表达式结构。
public String replaceAll(String regex ,Strig replacement):将满足正则标记的内容全部替换为新的内容。
public String replaceFirst(String regex,String replacement):将满足正则标记的首个内容替换为新的内容。
public String[] split(String regex):按照指定的正则标记进行字符串的全拆分。
public String[] split(String regex,int limit):按照指定的正则标记进行字符串的部分拆分。
实现字符串替换
public class TestDemo {
public static void main(String[] args) throws Exception {
String str="hello*)(*()yootk(*#mldn";
String regex="[^a-z]";
System.out.println(str.replaceAll(regex,""));
}
}
字符串拆分
public class TestDemo {
public static void main(String[] args) throws Exception {
String str="hello*)(*()yootk(*#mldn3r413453fh";
String regex="\\d+";
String result[]=str.split(regex);
for (int x=0;x<result.length;x++){
System.out.println(result[x]);
}
}
}
验证一个字符串是否是数字,如果是则将其变成double型
public class TestDemo {
public static void main(String[] args) throws Exception {
String str="10.10";
String regex="\\d+(\\.\\d+)?";
if (str.matches(regex)){
System.out.println(Double.parseDouble(str));
}
}
}
判断给定的字符串是否是一个IP地址
public class TestDemo {
public static void main(String[] args) throws Exception {
String str="192.168.1.1";
String regex="(\\d{1,3}\\.){3}\\d{1,3}";
System.out.println(str.matches(regex));
}
}
给定一个字符串,要求判断其是否是日期格式,如果是则将其转换为Date型数据。本次只验证"年-月-日"的日期格式,其中年包含4位数字,月与日分别包含2位数字。
public class TestDemo {
public static void main(String[] args) throws Exception {
String str="2013-08-15";
String regex="\\d{4}-\\d{2}-\\d{2}";
if (str.matches(regex)){
Date date=new SimpleDateFormat("yyy-MM-dd").parse(str);
System.out.println(date);
}
}
}
判断电话号码,一般要编写电话号码满足以下3种格式。
- 格式一:8312591
- 格式二:0797-8319591
- 格式三:(0797)-8312591
public class TestDemo {
public static void main(String[] args) throws Exception {
String str="(0797)-8312591";
String regex="((\\d{3,4}-)|(\\(\\d{3,4}\\)-))?\\d{7,8}";
System.out.println(str.matches(regex));
}
}
验证email地址,对于此验证假设有如下两种不同的格式要求。
- 格式要求一:email由字母、数字、“_"、“.”组成。
- 格式要求二:用户名要求由字母、数字、“_”、“.”组成,其中必须以字母开头,结尾只能是字母或数字,用户名长度为2~30,最后的域名后缀只能是.com、.cn、.net、.com.cn、.net.cn、.edu、.gov、.org其中的一个。
public class TestDemo {
public static void main(String[] args) throws Exception {
String str="mldn.100_lixinghua@yootk.com";
String regex="[a-zA-Z][a-zA-Z0-9_\\.]{0,28}[a-zA-Z0-9]"+"@\\w+\\.(com|net|cn|com\\.cn|net\\.cn|org|gov|edu)";
System.out.println(str.matches(regex));
}
}
10.8.4 java.util.regex包支持
在String类中提供的方法在Pattern或Matcher类中也提供了相同的功能。
(1)Pattern类中存在的方法
- 字符串全拆分:public String[] split(CharSequence input);
- 字符串部分拆分:public String[] split(CharSequence input,int limit).
(2)Matcher类中存在的方法
- 字符串匹配:public boolean matches();
- 字符串全替换:public String replaceFirst(String replacement)
利用Pattern类实现字符串拆分
import java.util.regex.Pattern;
public class TestDemo {
public static void main(String[] args) throws Exception {
String str="hello1yootk22mldn333lixinghua";
String regex="\\d+";
Pattern pattern=Pattern.compile(regex);
String result[]=pattern.split(str);
System.out.println(Arrays.toString(result));
}
}
实现字符串验证操作
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TestDemo {
public static void main(String[] args) throws Exception {
String str="100";
String regex="\\d+";
Pattern pattern=Pattern.compile(regex);
Matcher mat=pattern.matcher(str);
System.out.println(mat.matches());
}
}
10.9 反射机制
10.9.1 认识反射
所谓的反就是可以利用对象找到对象的出处
public class TestDemo {
public static void main(String[] args) throws Exception {
Date date=new Date();
System.out.println(date.getClass());
//直接实例化输出
}
}
//结果class java.util.Date
10.9.2 Class类对象实例化
当使用getClass()方法时,返回的类型为java.lang.Class,这是反射操作的源头类,即所有的反射操作都需要通过此类开始,而最关键的是这个类有以下3种实例化方法
第一种:调用Object类中的getClass()方法,但是如果要使用此类操作则必须有实例化对象。
public class TestDemo {
public static void main(String[] args) throws Exception {
Date date=new Date();
Class<?>cls=date.getClass();
System.out.println(cls.getName());
}
}
第二种:使用“类.class”取得,此时可以不需要通过指定类的实例化对象取得。
public class TestDemo {
public static void main(String[] args) throws Exception {
Class<?>cls=java.util.Date.class;
System.out.println(cls.getName());
}
}
第三种:调用Class类提供的方法:public static Class<?> forName(String classname)throws ClassNotFoundException.
public class TestDemo {
public static void main(String[] args) throws Exception {
Class<?>cls=Class.forName("java.util.Date");
System.out.println(cls.getName());
}
}
此时可以不使用import语句导入一个明确地类。
10.9.3 反射实例化对象
No. | 方法 | 类型 | 描述 |
---|---|---|---|
1 | public static Class<?> forName(String className)throws ClassNotFoundException | 普通 | 通过字符串设置的类名称实例化Class类对象。 |
2 | public Class<?>[] getInterfaces() | 普通 | 取得类实现的所有接口 |
3 | public String getName() | 普通 | 取得反射操作类的全名 |
4 | public String getSimpleName() | 普通 | 取得反射操作类名、不包括包名称 |
5 | public Package getPackage() | 普通 | 取得反射操作操作类所在的包 |
6 | public Class<? super T>getSuperclass() | 普通 | 取得反射操作类的父类 |
7 | public boolean isEunm() | 普通 | 反射操作的类是否是枚举 |
8 | public boolean isInterface() | 普通 | 反射操作的类是否是接口 |
9 | public boolean isArray() | 普通 | 反射操作类是否是数组 |
10 | public T newInstance() throws InstantiationException,IllegalAccessException | 普通 | 反射实例化对象 |
注意使用forName()时,一定要调用到包加类名称
在Class类的常用方法中最重要的就是newInstance()方法。
利用反射实例化对象
package com.company;
public class Book {
public Book(){
System.out.println("****Book是一本书");
}
@Override
public String toString(){
return "《朱小东大帅哥》";
}
}
public class TestDemo {
public static void main(String[] args) throws Exception {
Class<?> cls=Class.forName("com.company.Book");
Object obj=cls.newInstance();
Book book=(Book) obj;
System.out.println(book);
}
}
这样做的意义
利用关键字new进行对象的实例化操作是最正统的做法,也是实际开发中使用最多的操作。但是关键字new实例化对象时需要明确地指定类的构造方法,所以new是造成耦合的最大元凶。
10.9.4 使用反射调用构造
public Constructor<?>[] getConstructor() throws SecurityException:取得全部构造方法。
public ConstructorgetConstructor(Class<?> parameterTypes)throws NoSuchMethodException,SecurityException:取得指定参数类型的构造方法。
getExceptionTypes():返回构造方法上所有抛出异常的类型。
getModifiers():取得构造方法的修饰符
getName():取得构造方法的名字
getParameterCount():取得构造方法中的参数个数
getParameterTypes():取得构造方法中的参数类型
public T newInstance(Object…initargs)throws InstantiationException,IllegalArgumentException,IllegalArgumentException,Invocation TargetException:调用指定参数的构造实力化对象。
为什么修饰符的方法返回是int类型?
所有的修饰符都是一个数字,修饰符的组成就是一个数字的加法操作。
明确调用类中的有参构造
package com.company;
public class Book {
private String title;
private double price;
public Book(String title,double price){
this.title=title;
this.price=price;
}
@Override
public String toString(){
return "图书名称"+this.title+"价格:"+this.price;
}
}
public class TestDemo {
public static void main(String[] args) throws Exception {
Class<?> cls=Class.forName("com.company.Book");
Constructor<?> con=cls.getConstructor(String.class,double.class);
Object obj=con.newInstance("《朱小东自传》",88.8);
System.out.println(obj);
}
}
10.9.5 反射调用方法
public Method[] getMethods() throws SecurityException:取得类中的全部方法
public Method getMethod(String name,Class<?>…parameterTypes)throws NoSuchMethodException,SecurityException:取得类中指定方法名称与参数类型的方法
public int getModifiers():取得方法的修饰符
public Class<?>getReturnType():取得方法的返回值类型
public Class<?>[] getParameterTypes():取得方法中定义的所有参数类型
public Object invoke(Object obj,Object…args)throws IllegalAccessException,IllegalArgumentException,InvocationTargetException:反射调用方法并且传递执行方法所需要的参数数据。
public Class<?>[] getExceptionTypes():取得方法抛出的异常类型
使用反射操作简单Java类的属性
public class Book {
private String title;
public void setTitle(String title){
this.title=title;
}
public String getTitle(){
return title;
}
}
public class TestDemo {
public static void main(String[] args) throws Exception {
String fieldName="title";
Class<?>cls=Class.forName("com.company.Book");
Object obj=cls.newInstance();
//取得类中的setTitle(),由于title需要首大写字母,所以调用init()处理,参数类型为String
Method setMet=cls.getMethod("set"+initcap(fieldName),String.class);
Method getMet=cls.getMethod("get"+initcap(fieldName));
setMet.invoke(obj,"java开发实战");
System.out.println(getMet.invoke(obj));
}
public static String initcap(String str){
return str.substring(0,1).toUpperCase()+str.substring(1);
}
}
10.9.6 反射调用成员
Class类中取得成员的操作
public Field[] getDeclaredFields() throws SecurityException:取得本类定义的全部成员
public Field getDeclared(String name)throws NoSuchFieldException,SecurityException:取得本类指定名称的成员
public Field[] getFields() throws SecurityException:取得本类继承父类的全部成员
public Field getField(String name)throws NoSuchFieldException,SecurityException:取得本类继承父类中指定名称的成员。
Field类中的常用方法
public Class get(Object obj)throws IllegalArgumentException,IllegalAccessException:取得本类继承父类中指定名称的成员。
public Class<?>getType():取得该成员的类型
public void set(Object obj,Object value)throws IllegalArgumentException,IllegalAccessException:设置指定对象中的成员内容,相当于直接利用对象调用成员设置内容。
利用反射直接操作私有成员
public class Book {
private String title;
}
public class TestDemo {
public static void main(String[] args) throws Exception {
Class<?>cls=Class.forName("com.company.Book");
Object obj=cls.newInstance();
Field titleField=cls.getDeclaredField("title");
titleField.setAccessible(true);
titleField.set(obj,"java开发实战经典");
System.out.println(titleField.get(obj));
}
}
本程序首先直接取得了本类声明的title属性,由于title属性使用了private封装无法被外部直接访问,则利用setAccessible()方法取消封装,然后传入指定的类的实例化对象,就可以直接进行属性内容的设置与取得。
10.10 国际化
国际化程序指的是同一套程序代码可以在不同的国家使用,那么在假设项目功能不变的情况下,文字就成为这一操作中最为重要的处理环节。
10.10.1 使用Locale类定义语言环境
Locale类的常用方法
public Locale(String language,String country):设置要使用的语言以及国家编码
public static Locale getDefault():取得当前语言环境下的Locale类对象
输出Locale类对象
public class TestDemo {
public static void main(String[] args) throws Exception {
Locale loc=Locale.getDefault();
System.out.println(loc);
}
}
10.10.2 利用ResourceBundle读取资源文件
资源文件一般都是以“key=value”的形式保存文本信息,这样在进行信息读取时就可以根据指定的key取得对应的value数据,但是资源文件的文件名称是有要求的,必须以"*.properties"作为文件后缀。如果要在程序中读取资源文件,则可以利用java.util.ResourceBundle类完成。
ResourceBundle类的常用方法
public static final ResourceBundle getBundle(String baseName):根据当前默认语言环境,取得资源对象。
public static final ResourceBundle getBundle(String baseName,Locale locale):根据指定的语言环境,取得资源对象。
public final String getString(String key):根据key取得对应的value数据。