------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
●反射的基石-----Class
java类用于描述一类事物的共性,该类事物有什么属性,没有什么属性,至于这个属性的值是什么,则是由这个类的实例对象来确定的,不同的实例对象有什么不同的属性值。Class描述了类的名字,类的访问属性,类所属于的包名,字段名称的列表,方法名称的列表,等
Class cls = 类名.class
Class cls = 对象.getClass()
Class cls = class.forName(“java.lang.String”)
三种方式得到字节码
●Class
类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该Class
对象。基本的 Java 类型(boolean
、byte
、char
、short
、int
、long
、float
和 double
)和关键字 void
也表示为 Class
对象。
●public static void main(String[] args) throws ClassNotFoundException {
String s = "abc";
Class cls1 = String.class;
Class cls2 = s.getClass();
Class cls3 = Class.forName("java.lang.String");
}
基本数据类型
System.out.println(void.class.isPrimitive());//true
System.out.println(int.class.isPrimitive());//true
System.out.println(Integer.class.isPrimitive());//false
System.out.println(Integer.class==int.class);//false
System.out.println(int.class==Integer.TYPE);//true
System.out.println(int[].class.isPrimitive());//false
System.out.println(int[].class.isArray());//true 判断数组方法
●反射就是把java类中的各种成分映射成相应的java类
●java反射机制:
在java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意任意对象,能否调用它的方法?这种动态获取类的信息,以及动态调用类的方法的功能来源于JAVA反射,从而使java具有动态语言的特点
●java反射机制主要提供了一下几种方法
(1)在运行是判读哪任意一个对象所属的类
(2)在运行时构造任意一个类的对象
(3)在运行时判断任意一个类锁具有的成员变量和方法
(4)在运行时调用任意一个对象的方法
●java反射相关的API简介
位于java.lang.reflect包中
Class类:代表一个类
Field类:代表类的成员变量
Method类:代表类的方法
Constructor类:代表类的构造方法
Array类:提供了动态创建数组,以及访问数组的元素的静态方法,该类中的所有方法都是静态方法
●Constructor类
得到某个类所有构造方法
Constructor[] constructor = Class.forName("java.lang.String").getConstructors();
Constructor constructor =
Class.forName("java.lang.String").getConstructor(byte[].class);
●创建对象
利用Constructor创建对象
Class declaringClass = constructor.getDeclaringClass();
System.out.println(declaringClass);
System.out.println(constructor.getModifiers());
byte[] b = "nihao".getBytes();
String string = (String)constructor.newInstance(b);
System.out.println(string);
利用Class.newInstance创建对象 无参构造方法
String newInstance = String.class.newInstance();
●Field类
Field类代表某个类中的一个成员变量
class Pointer{
private int x;
public int y;
public Pointer(int x, int y) {
super();
this.x = x;
this.y = y;
}
}
public class ReflectDemo {
public static void main(String[] args) throws Exception {
Pointer pt1= new Pointer(3,5);
Field fieldy = pt1.getClass().getField("y");
Object object = fieldy.get(pt1);
System.out.println(object);
Field fieldx = pt1.getClass().getDeclaredField("x");
fieldx.setAccessible(true);
Object object2 = fieldx.get(pt1);
System.out.println(object2);
}
}
●综合案例
class Pointer{
private int x;
public int y;
public String str1 = "baseball";
public String str2 = "bbbb";
public String str3 = "basketball";
public Pointer(int x, int y) {
super();
this.x = x;
this.y = y;
}
@Override
public String toString() {
return "Pointer[str1=" + str1 + ",str2=" + str2 + ",str3=" + str3
+ ", x=" + x + ", y=" + y + "]";
}
}
public class ReflectDemo {
public static void main(String[] args) throws Exception {
Pointer pt1= new Pointer(3,5);
Field[] fields = pt1.getClass().getFields();
for (Field field : fields) {
//if(field.getType().equals(String.class)){
//因为是使用同一份字节码,所以使用==号
if(field.getType()==String.class){
String oldString =(String) field.get(pt1);
String newString =oldString.replace('b', 's');
field.set(pt1, newString);
}
}
System.out.println(pt1);
}
}
●Method
代表某个类中的一个成员方法
public static void main(String[] args) throws Exception {
String str = "abc";
Method method = str.getClass().getMethod("charAt", int.class);
System.out.println(method.invoke(str, 1));
System.out.println(method.invoke(str, new Object[]{2}));
//System.out.println(method.invoke(null,1)); // null表示静态方法调用不需要对象
}
●方法调用传递数组
public static void main(String[] args) throws Exception {
String startingClass =args[0];
Method mainMethod = Class.forName(startingClass).getMethod("main",String[].class);
mainMethod.invoke(null,(Object)new String[]{"111","222","333"});
mainMethod.invoke(null, new Object[]{new String[]{"111","222","333"}});
}
●数组的反射
每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该Class
对象。
Element Type | Encoding |
boolean | Z |
byte | B |
char | C |
class or interface | Lclassname; |
double | D |
float | F |
int | I |
long | J |
short | S |
●数组和Object的关系
public static void main(String[] args) throws Exception {
int[][] i = new int[1][2];
int[] l = new int[1];
Integer[][] j = new Integer[2][3];
Integer[] k = new Integer[2];
Object[] b = i;//正确
Object[] c = j;//正确
Object[] d = k;//正确
Object[] e = l;//错误的
}
●数组反射
public static void printObject(Object obj) {
Class cls = obj.getClass();
if (cls.isArray()) {
int len = Array.getLength(obj);
for (int i = 0; i < len; i++) {
System.out.println(Array.get(obj, i));
}
}
}
数组中每一个元素的类型
a[0].getClass().getName();
●ArrayList_HashSet的比较及Hashcode分析
内存泄漏之hashCode
当以个对象被存储进了HashSet集合中以后,就不能修改这个对象中的哪些参与计算哈希值的字段了,否则,对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不同了,在这种情况下,即使在contains方法使用该对像的当前引用作为的参数去HashSet集合中检索对象,也将返回找不到对象的结果,这也会导致无法从HashSet集合中单独删除当前对象,从而造成内存泄漏