在一些组件或者 框架中开发中,他们本身是不知道要处理哪些类,
例如jackson组件,我们给他什么类,他就要处理转换什么类
new ObjectMapper().writeValueAsString(user)
new ObjectMapper().writeValueAsString(admin)
new ObjectMapper().writeValueAsString(result)
在web.xml中配置了哪些servlet类,tomcat就要创建哪些类对象
<servlet-class>com.ffyc.dorm.web.LoginServlet</servlet-class>
<servlet-class>com.ffyc.dorm.web.TestServlet</servlet-class>
在mybatis中,给了什么类型,mybatis就可以将结果封装映射到给定的类的对象中
<select id="findAdminByld" parameterType="int" resultType="Admin">
<select id="teachers" resultType="com.ffyc.mybatispro.model.Teacher">
以前已知类名的使用方式,可以看做是正向使用类.
框架需要对任意类处理时,只是知道类的名字,通过类的名字动态才去获取类中的信息.
把这种对类的使用方式,称为反向使用.
反射:
在运行状态中,在只知道一个类名时,可以动态获取类中信息,创建对象,调用对象中成员的机制称为java反射机制。
作用:动态获取类信息。
java反射相关的类主要包括:
Class 类型
Constructor 构造方法
Method 方法
Field 属性
除了Class外,其他类都位于java.lang.reflect包中;Class类位于java.lang.Class包中。
Class
位于java.lang.Class包里,
Class类的对象,就是当前正在运行中的类和接口,可以通过Class类的对象调用正运行类中的成员变量和方法。
如何获得类的Class对象?
方式1:知道类的地址
Class.forName(包名+类名)
方式2:知道类名
类名.class;
方式3:知道类名,且对象实例化的情况下。
对象名.getClass();
public class Test1 {
public static void main(String[] args) throws ClassNotFoundException {
//以前使用类,已知类名,new创建对象,调用成员方法
//User user = new User();
//user.eat();
//使用反射机制时,知道类的名称(包名+类名)
String classname = "com.ffyc.javareflect.User";
//如何获得类的信息?
// 通过Class类来获取类中信息
//如何获得类的Class对象?
//方式1:知道类的名称(包名+类名)
Class clazz =Class.forName(classname);
System.out.println(clazz);
//方式2: 类名.class;
Class clazz1 = User.class;
System.out.println(clazz==clazz1);
//方式3:知道类名,且对象实例化的情况下。
User user=new User();
Car car = new Car();
Class clazz2 =user.getClass();
Class clazz3 =car.getClass();
clazz2.getFields();
clazz3.getFields();
System.out.println(clazz1==clazz2);
}
}
java中创建对象的方式:
1.new 2.反序列化 3.反射机制 4.对象克隆
反射机制创建对象:
1.先获得Class对象;
Class clazz =Class.forName("com.ffyc.javareflect.User");
2.通过类的Class对象,创建对象。
Object object = clazz.newInstance();
3.获得类中构造方法,通过构造方法api中的方法创建对象
//无参
Constructor constructor= clazz.getConstructor();//获得类中的构造方法
Object object1 = constructor.newInstance();//通过构造方法创建的对象。
//有参
Constructor constructor1 = clazz.getConstructor(String.class,String.class);
Object object2 = constructor1.newInstance("张三","111");
获得所有公共的构造方法:
Constructor [] constructors = clazz.getConstructors();
获得类中的成员变量:
获得公有成员变量:
Field accountfield = clazz.getField("account");
获得类中所有的成员变量(无论公有和私有)
Field[] declaredFields =clazz.getDeclaredFields();
.setAccessible()方法用于操作成员中的私有属性:
for(Field field:declaredFields){
field.setAccessible(true);//语句用来允许操作类中成员的私有属性,正常不建议使用
field.set(object, map.get(field.getName()));
}
获得类中的成员方法:
String classname = "com.ffyc.javareflect.User";
Class clazz =Class.forName(classname);
Object object = clazz.newInstance();
//获得类中的成员方法
Method method=clazz.getMethod("eat");
method.invoke(object);//调用方法
Method method1=clazz.getMethod("eat", String.class);
method1.invoke(object, "张三");
反射的优缺点:
优点:
● 1.增加程序的灵活性,可以在运行的过程中动态对类进行修改和操作
● 2.提高代码的复用率,比如动态代理
● 3.可以在运行时轻松获取任意一个类的方法、属性,并且还能通过反射进行动态 调用
缺点:
● 1.反射会涉及到动态类型的解析,导致性能要比非反射调用更低
● 2.使用反射技术通常要在一个没有安全限制的程序运行.
● 3.反射可以绕过一些限制访问的属性或者方法,可能会导致破坏代码本身的抽象性