/*
* 反射的基石——>Class类
*
* class
* Class——>代表一类什么样事物?
* 1、Java类用于描述一类事物的共性,该类事物有什么属性,没有什么属性,至于这个属性的值是什么,则是由这个类的实例对象
* 来确定的,不同的实例对象有不同的属性值。Java程序中的各个Java类,他们是否属于同一类事物?是不是可以用一个类来描述
* 这类事物呢?这个类的名字就是Class,要注意与小写class关键字的区别。Class类描述了哪些方面的信息呢?类的名字,类的
* 访问属性,类所属于的包名,字段名称的列表,方法名称的列表,等等。学习反射,首先就要明白Class这个类。
*
* (1)、Java程序中的各个Java类属于同一类事物,描述这类食物的Java类名就是Class
*
* (2)、对比提问:众多的人用一个什么类来表示?众多的JavaJava类用一个什么类来表示?
*
* 人————>Person
* Java类——>Class
*
* (3)、对比提问:Person类代表人,它的实例对象就是张三、李四这样一个个具体的人,Class类代表Java类,它的各个实例对象
* 又分别对应什么呢?
*
* 对应各个类在内存中的字节码,例如,Person类的字节码,ArrayList类的字节码,等等。
*
* 一个类被类加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码,不同的类的字节码是不同的,
* 所以它们在内存中的内容是不同的,这一个个的空间可分别用一个个的对象来表示,这些对象显然具有相同的类型,这个
* 类型是什么呢?
*
* (4)、如何得到各个字节码对应的实例对象(Class类型)
* 类名.class,例如:System.class
* 对象:getClass(),例如,new Date().getClass()
* Class.forName("类名"),例如,Class.forName("java.util.Date");
*
* (5)、九个预定义Class实例对象:
* 参看Class.isPrimitive方法的帮助
* Int.class==Integer.TYPE
*
* (6)、数组类型的class实例对象
* Class.isArray()
* 总之,只要是在源程序中出现的类型,都有各自的Class实例对象,例如:int[],void.....
*
* Person p1=new Person();
* Person p2=new Person();
*
* Date
* Math
*
* Class cls1=Date.class;//字节码1
* class cls2=Person.class;//字节码2
*
* p1.getClass();
* Class.forName("java.lang.String")
*
* 反射:
* 1、反射就是把java类中的各种成分映射成相应的java类。例如,一个java类中用一个Class类的对象来表示,
* 一个类中的组成部分:成员变量,方法:构造方法,包等等信息也用一个个的java类来表示,就像汽车是一个类,
* 汽车中的发动机,变速箱等等也是一个个的类。表示java类的Class类显然要提供一系列的方法,来获得其中的变量,方法,
* 构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,它们是Field、Method、Constructor、Package等等
*
* 2、一个类中的每一个成员都可以用相应的反射API类的一个实例对象来表示,通过调用Class类的方法可以得到这些实例对象后,
* 得到这些实例对象后有什么用呢?怎么用呢?这正是学习和应用反射的要点。
*/
public class ReflectTest
{
public static void main(String[] args)throws Exception
{
String str1="abc";
Class cls1=str1.getClass();
Class cls2=String.class;
Class cls3=Class.forName("java.lang.String");
System.out.println(cls1==cls2);
System.out.println(cls1==cls3);
System.out.println(cls1.isPrimitive());
System.out.println(int.class.isPrimitive());
System.out.println(int.class==Integer.class);
System.out.println(int.class==Integer.TYPE);
System.out.println(int[].class.isPrimitive());
System.out.println(int[].class.isArray());
/*
* 如何得到String(StringBuffer buffer)构造方法?
* 构造方法里传的是参数类型StringBuffer
*
* 如果想得到两个参数的构造方法,可以传两个参数写为:
* Constructor constructor1=String.class.getConstructor(StringBuffer.class,int.class);
* 可以写多个参数
*/
//new String(new StringBuffer("abc"));
Constructor constructor1=String.class.getConstructor(StringBuffer.class);
String str2=(String)constructor1.newInstance(new StringBuffer("abc"));
System.out.println(str2.charAt(2));
}
}
/*
运行结果为:
true
true
false
true
false
true
false
true
c
*/
/*
* Constructor类:
* Constructor类代表某个类中的一个构造方法
*
* 1、得到某个类所有的构造方法:
* 例子:Constructor[] constructor=Class.forName("java.lang.String").getConstructors();
*
* 2、得到某一个构造方法:
* 例子:Constructor constructor=Class.forName("java.lang.String").getConstructor(StringBuffer.class);
* //获得方法时要用到类型
*
* 3、创建实例对象:
* 通常方式:String str=new String(new StringBuffer("abc"));
* 反射方式:String str=(String)constructor.newInstance(new StringBuffer("abc"));
* //调用获得的方法时要用到上面相同类型的实例对象
*
* 4、Class.newInstance()方法:
* 例子:String obj=(String)Class.forName("java.lang.String").newInstance();
* 该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。
* 该方法内部的具体代码是怎样写的呢?用到了缓存机制来保存默认构造方法的实例对象
*/
黑马程序员—反射的深入讲解
最新推荐文章于 2023-01-08 10:51:16 发布