黑马程序员——java反射

来源:互联网 发布:mac翻墙回国的软件 编辑:程序博客网 时间:2024/06/17 15:09

------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 类型(booleanbytecharshortintlongfloatdouble)和关键字 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 Stringstr1 = "baseball";

    public Stringstr2 = "bbbb";

    public Stringstr3 = "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集合中单独删除当前对象,从而造成内存泄漏

 

0 0