反射及国际化问题

Java中的反射-reflect

反射:java.lang.reflect

  • 如何动态的创建一个类?
  • 如何动态的调用一个方法?
  • 如何知道一个类所有的方法?

动态的构造一个类

Method1 不传递任何构造参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//ch11.DynamicCreate01
package ch11;
/**
* 本例子演示了如何动态构建
*/
public class DynamicCreate01 {
public static void main(String[] args) {
try {
//要动态创建的类的全名
String className = "ch11.Student";
Class clazz = Class.forName(className);
//实例化,本例子要求"ch11.Student"必须有无参数的构造方法。
Object obj = clazz.newInstance();
Student student = (Student) obj;
System.out.println("obj.class=" + obj.getClass().toString());
System.out.println("student.class=" + student.getClass().toString());
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
//ch11.DynamicCreat02
package ch11;
import java.lang.reflect.InvocationTargetException;
/**
* 本例子演示了如何动态构建
*/
public class DynamicCreate02 {
public static void main(String[] args) {
try {
String className = "ch11.Student";
Class clazz = Class.forName(className);
//动态构造的另外一种方法,这种方法和DynamicCreate01类似
Object obj = clazz.getConstructor(new Class[0]).newInstance();
Student student = (Student) obj;
System.out.println("obj.class=" + obj.getClass().toString());
System.out.println("student.class=" + student.getClass().toString());
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}

Method2 调用带有参数的构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
//ch11.DynamicCreate03
package ch11;
import java.lang.reflect.InvocationTargetException;
/**
* 本例子演示了如何动态构建
*/
public class DynamicCreate03 {
public static void main(String[] args) {
try {
String className = "ch11.Student";
Class clazz = Class.forName(className);
Class[] classes = new Class[2];
classes[0] = String.class;
classes[1] = Integer.class;
// clazz.getConstructor(classes) 寻找Student的带有参数的构造函数
// 且构造函数的第一个是参数String,第二个是Integer。
// .newInstance("tom", 123): 用"tom", 123 实例化
Object obj = clazz.getConstructor(classes).newInstance("tom", 123);
Student student = (Student) obj;
System.out.println("obj.class=" + obj.getClass().toString());
System.out.println("student.class=" + student.getClass().toString());
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
//ch11.DynamicCreate04
package ch11;
import java.lang.reflect.InvocationTargetException;
/**
* 本例子演示了如何动态构建
*/
public class DynamicCreate04 {

public static void main(String[] args) {
try {
String className = "ch11.Student";
//用变长参数调用
Object obj = createObject4(className, "aaa", 456);
Student student = (Student) obj;
System.out.println("obj.class=" + obj.getClass().toString());
System.out.println("student.class=" + student.getClass().toString());

} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
public static Object createObject4(String className, Object... values)
throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException, NoSuchMethodException, SecurityException {
Class clazz = Class.forName(className);
Class[] classes = new Class[values.length];
for (int i = 0; i < classes.length; i++) {
classes[i] = values[i].getClass();
}
Object obj = clazz.getConstructor(classes).newInstance(values);
return obj;
}
}
//ch11.DynamicCreate04
package ch11;
import java.lang.reflect.InvocationTargetException;
/**
* 本例子演示了如何动态构建
*/
public class DynamicCreate04 {
public static void main(String[] args) {
try {
String className = "ch11.Student";
//用变长参数调用
Object obj = createObject4(className, "aaa", 456);
Student student = (Student) obj;
System.out.println("obj.class=" + obj.getClass().toString());
System.out.println("student.class=" + student.getClass().toString());
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
public static Object createObject4(String className, Object... values)
throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException, NoSuchMethodException, SecurityException {
Class clazz = Class.forName(className);
Class[] classes = new Class[values.length];
for (int i = 0; i < classes.length; i++) {
classes[i] = values[i].getClass();
}
Object obj = clazz.getConstructor(classes).newInstance(values);
return obj;
}
}

动态的调用一个方法

Method1 调用无参数方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//ch11.DynamicInvoke01
package ch11;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 这个例子展示了如何动态的调用一个带有参数的方法
*/
public class DynamicInvoke01 {
public static void main(String[] args) {
Student student = new Student("jack", 123);
try {
System.out.println(dynamicInvokeMethod(student,"getName"));
Object result=dynamicInvokeMethod(student, "getName");
System.out.println(result);
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
public static Object dynamicInvokeMethod(Object obj, String methodName) throws IllegalAccessException,
InvocationTargetException, NoSuchMethodException, SecurityException {
Method method = obj.getClass().getMethod(methodName);
return method.invoke(obj);
}
}

Method2 调用有参数方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//ch11.DynamicInvoke02
package ch11;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 这个例子展示了如何动态的调用一个带有参数的方法
*/
public class DynamicInvoke02 {
public static void main(String[] args) {
Student student = new Student("jack", 123);
try {
dynamicInvokeMethod (student, "setName", "tom");
System.out.println(student.getName());
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
public static Object dynamicInvokeMethod (Object obj, String methodName, Object... values)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException,
SecurityException, ClassNotFoundException {
Class[] classes = new Class[values.length];
for (int i = 0; i < values.length; i++) {
classes[i] = values[i].getClass();
}
Method method = obj.getClass().getMethod(methodName, classes);
return method.invoke(obj, values);
}
}

Method3 包含原始数据类型的方法动态调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//ch11.DynamicInvoke03
package ch11;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 这个例子展示了如何动态调用带有原始数据类型的函数
*/
public class DynamicInvoke03 {
public static void main(String[] args) {
StudentPrime student = new StudentPrime("jack", 123);
try {
dynamicInvokeMethod1(student, "setAge", 20);
dynamicInvokeMethod2(student, "setAge", 20);
System.out.println(student.getAge());
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
/**
* 这个方法是错误的,无法调用原始数据类型的方法
* @param obj
* @param methodName
* @param values
* @return
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
* @throws NoSuchMethodException
* @throws SecurityException
* @throws ClassNotFoundException
*/
public static Object dynamicInvokeMethod1(Object obj, String methodName, Object... values)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException,
SecurityException, ClassNotFoundException {
Class[] classes = new Class[values.length];
for (int i = 0; i < values.length; i++) {
classes[i] = values[i].getClass();
}
Method method = obj.getClass().getMethod(methodName, classes);
return method.invoke(obj, values);
}
/**
* 这个方法可以调用包含int参数的方法
* @param obj
* @param methodName
* @param values
* @return
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
* @throws NoSuchMethodException
* @throws SecurityException
* @throws ClassNotFoundException
*/
public static Object dynamicInvokeMethod2(Object obj, String methodName, Object... values)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException,
SecurityException, ClassNotFoundException {
Class[] classes = new Class[values.length];
for (int i = 0; i < values.length; i++) {
if (values[i] instanceof Integer) {
classes[i] = Integer.TYPE;
classes[i] = int.class;
} else {
classes[i] = values[i].getClass();
}
}
Method method = obj.getClass().getMethod(methodName, classes);
return method.invoke(obj, values);
}
}
//class StudentPrime
package ch11;
public class StudentPrime {
private String name;
private String school;
private int age;
private int id;
public StudentPrime(String name, Integer id) {
super();
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}

动态调用属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//ch11.DynamicField.java
package ch11;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
public class DynamicField {
public static void main(String[] args) {
Object obj = new StudentPublic("jack", 123);
try {
dynamicField(obj, "name", "tom");
System.out.println(((StudentPublic) obj).getName());
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
public static void dynamicField(Object obj, String fieldName, Object value) throws IllegalAccessException,
IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, NoSuchFieldException {
//取得所有public类型的属性
Field field = obj.getClass().getField(fieldName);
//直接设置属性值
field.set(obj, value);
}
}

Java中的乱码问题

Java乱码的根源

1

  • 同样的byte[]在不同的编码方式下表示不同的字符
  • char→byte[]同样存在上述问题
  • Java内部采用Unicode

7

8

字符集

定义

字符的集合

常见字符集

  • ASCII:美国信息交换标准码,共128个(0~127)
  • iso8859-1:西欧语言,包含多种语言,兼容ASCII

2

  • gb2312/GBK:
    • 《信息交换用汉字编码字符集——基本集》
    • 由中国国家标准总局发布,与1981年5月实施
    • GBK字符集兼容bg2312
  • Unicode
    • 统一码、万国码、单一码
    • Unicode用数字0~0x10FFFF来映射这些字符最多可以容纳1114112个字符,或者说有1114112个码位
    • 目前Unicode分为17个平面(plane),每平面拥有65536个码点,最初的65536个字符在0号平面

字符编码方案

字符编码方案是从一个或多个编码字符集到一个或多个固定宽度代码单元序列的映射

  • gb2312/GBK

    • 将区位码直接保存在2个字节中
    • 例如:啊 - B0A0
  • Unicode

    • UTF-32
    • UTF-16

    4

    • UTF-8
      • 1~4个字节变长编码

3

实例

“汽车”在不同编码下的结果

5

二进制[C6 FB]表示什么

6

解决乱码方法

charsetName一致

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//ch11.CharSetDemo
String.getByte(String charsetName);
new String(byte[] data,String charsetName);
InputStreamReader inReader=new InputStreamReader(InputStream in,String charsetName);
//
package ch11;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
/**
* 这个例子演示了java乱码及解决的原理
*/
public class CharSetDemo {
public CharSetDemo() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) {
readStrFromFile("D:/course/course/code_demo/src/ch11/char1.txt");
readStrFromFile("D:/course/course/code_demo/src/ch11/char2.txt");
byteToStr();
}
public static void byteToStr() {
String str = "你好";
String str2 = "";
System.out.println(str2);
try {
//char->byte byte-char 使用了不同的编码 可能会导致混乱
str2 = new String(str.getBytes("gbk"), "utf-8");
System.out.println(str2);
str2 = new String(str.getBytes("gbk"), "gbk");
System.out.println(str2);
str2 = new String(str.getBytes("utf-8"), "utf-8");
System.out.println(str2);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 从文本文件中读取内容
* @param filename
*/
public static void readStrFromFile(String filename) {
try {
//读取byte
byte[] data = readBytes(filename);
//以utf-8方式构造字符串
String str = new String(data, "utf-8");
System.out.println(str);
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
public static byte[] readBytes(String filename) throws FileNotFoundException, IOException {
File src = null;
int totalReaded = 0;
int readed = 0;
FileInputStream reader = null;
byte data[];
try {
src = new File(filename);
Long len = src.length();
data = new byte[len.intValue()];
for (reader = new FileInputStream(filename); reader.available() > 0;) {
readed = reader.read(data, totalReaded, (len.intValue() - totalReaded));
totalReaded += readed;
}
} finally {
close(reader);
}
return data;
}
/**
* 关闭一个输入 输出流
* @param inout
*/
public static void close(Closeable inout) {
if (inout != null) {
try {
inout.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

Java中的国际化问题

9

Points

  • Java中的不定长参数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public class VariantParams{
    public static void main(String[] args){
    List<String> list=asList("a","b","c");
    for(String str:list){
    System.out.println(str);
    }
    }
    public static <T> list<T> asList(T... a){
    //不定长参数a是一个数组
    java.util.ArrayList<T> list=new ArrayList<t>();
    for(int i=0;i<a.length;i++){
    list.add(a[i]);
    }
    return list;
    }
    }
  • asList

文章源码

文章源码 备用仓库