第十章 Java常用类库

第十章 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.方法类型描述
1public static Class<?> forName(String className)throws ClassNotFoundException普通通过字符串设置的类名称实例化Class类对象。
2public Class<?>[] getInterfaces()普通取得类实现的所有接口
3public String getName()普通取得反射操作类的全名
4public String getSimpleName()普通取得反射操作类名、不包括包名称
5public Package getPackage()普通取得反射操作操作类所在的包
6public Class<? super T>getSuperclass()普通取得反射操作类的父类
7public boolean isEunm()普通反射操作的类是否是枚举
8public boolean isInterface()普通反射操作的类是否是接口
9public boolean isArray()普通反射操作类是否是数组
10public 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数据。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值