java反射工厂模式_118.Java反射-工厂模式

反射

类字节码文件是在硬盘上存储的,是一个个的.class文件。我们在new一个对象时,JVM会先把字节码文件的信息读出来放到内存中,第二次用时,就不用在加载了,而是直接使用之前缓存的这个字节码信息。

字节码的信息包括:类名、声明的方法、声明的字段等信息。在Java中“万物皆对象”,这些信息当然也需要封装一个对象,这就是Class类、Method类、Field类。

通过Class类、Method类、Field类等等类可以得到这个类型的一些信息,甚至可以不用new关键字就创建一个实例,可以执行一个对象中的方法,设置或获取字段的值,这就是反射技术。

Class类

获取Class对象的三种方式

Java中有一个Class类用于代表某一个类的字节码。

Java提供了三种方式获取类的字节码

forName()。forName方法用于加载某个类的字节码到内存中,并使用class对象进行封装

类名.class

对象.getClass()

/*** 加载类的字节码的3种方式

*@throwsException

**/

public void test1() throwsException {//方式一

Class clazz1 = Class.forName("cn.itcast.gz.reflect.Person");//方式二

Class clazz2 = Person.class;//方式三

Person p1 = newPerson();

Class clazz3=p1.getClass();

}

通过Class类获取类型的一些信息

1. getName()类的名称(全名,全限定名)

2 getSimpleName()类的的简单名称(不带包名)

3. getModifiers(); 类的的修饰符

4.创建对象

无参数构造创建对象

newInstance()

5. 获取指定参数的构造器对象,并可以使用Constructor对象创建一个实例

Constructor getConstructor(Class>... parameterTypes)

/*** 通过Class对象获取类的一些信息

*

*@throwsException

**/

private static void test2() throwsException {

Class clazz1= Class.forName("cn.itcast.gz.reflect.Person");//获取类的名称

String name =clazz1.getName();

System.out.println(name);//cn.itcast.gz.reflect.Person//获取类的简单名称

System.out.println(clazz1.getSimpleName()); //Person//获取类的修饰符

int modifiers =clazz1.getModifiers();

System.out.println(modifiers);//构建对象(默认调用无参数构造.)

Object ins =clazz1.newInstance();

Person p=(Person) ins;

System.out.println(p);//cn.itcast.gz.reflect.Person@c17164//获取指定参数的构造函数

Constructor> con = clazz1.getConstructor(String.class, int.class);//使用Constructor创建对象.

Object p1 = con.newInstance("jack", 28);

System.out.println(((Person) p1).getName());

}

通过Class类获取类型中的方法的信息

1.获取公共方法包括继承的父类的方法

getMethods()返回一个数组,元素类型是Method

2.获取指定参数的公共方法

getMethod("setName", String.class);

3.获得所有的方法,包括私有

Method[] getDeclaredMethods()

4.获得指定参数的方法,包括私有

Method getDeclaredMethod(String name, Class>... parameterTypes)

/*** 获取公有方法.

*@throwsException

**/

private static void test3() throwsException {

Class clazz1= Class.forName("cn.itcast.gz.reflect.Person");//1.获取非私用方法(包括父类继承的方法)

Method[] methods =clazz1.getMethods();

System.out.println(methods.length);for(Method m : methods) {//System.out.println(m.getName());

if ("eat".equals(m.getName())) {

m.invoke(clazz1.newInstance(),null);

}

}

}

/*** 获取指定方法签名的方法

*

*@throwsException

**/

private static void test4() throwsException {

Class clazz1= Class.forName("cn.itcast.gz.reflect.Person");//获取指定名称的函数

Method method1 = clazz1.getMethod("eat", null);

method1.invoke(new Person(), null);

}

/*** 获取指定方法名且有参数的方法

*

*@throwsException

**/

private static void test5() throwsException {

Class clazz1= Class.forName("cn.itcast.gz.reflect.Person");

Method method= clazz1.getMethod("eat", String.class);

method.invoke(new Person(), "包子");

}/*** 获取指定方法名,参数列表为空的方法.

*

*@throwsException

**/

private static void test4() throwsException {

Class clazz1= Class.forName("cn.itcast.gz.reflect.Person");//获取指定名称的函数

Method method1 = clazz1.getMethod("eat", null);

method1.invoke(new Person(), null);

}

/*** 反射静态方法

*@throwsException

**/

private static void test7() throwsException {

Class clazz1= Class.forName("cn.itcast.gz.reflect.Person");

Method method= clazz1.getMethod("play", null);

method.invoke(null, null);

}/*** 访问私有方法 暴力反射

*@throwsException

**/

private static void test6() throwsException {

Class clazz1= Class.forName("cn.itcast.gz.reflect.Person");

Method method= clazz1.getDeclaredMethod("movie", String.class);

method.setAccessible(true);

method.invoke(new Person(), "苍老师");

}

通过Class类获取类型中的字段的信息

1.获取公共字段

Field[] getFields()

2.获取指定参数的公共字段

Field getField(String name)

3.获取所有的字段

Field[] getDeclaredFields()

4.获取指定参数的字段,包括私用

Field getDeclaredField(String name)

/*** 获取公有的字段

**/

private static void test8() throwsException {

Class clazz1= Class.forName("cn.itcast.gz.reflect.Person");

Field[] fields=clazz1.getFields();

Person p= newPerson();

System.out.println(fields.length);for(Field f : fields) {

System.out.println(f.getName());if ("name".equals(f.getName())) {

System.out.println(f.getType().getName());

f.set(p,"jack");

}

}

System.out.println(p.getName());

}

/*** 获取私有的字段

*@throwsException

**/

private static void test9() throwsException {

Class clazz1= Class.forName("cn.itcast.gz.reflect.Person");

Field field= clazz1.getDeclaredField("age");

System.out.println(field.getName());

field.setAccessible(true);

Person p= newPerson();

field.set(p,100);

System.out.println(p.getAge());

}

工厂模式

Factory

例如:汽车销售商场

该模式将创建对象的过程放在了一个静态方法中来实现.在实际编程中,如果需要大量的创建对象,该模式是比较理想的.

public classDemo1 {public static voidmain(String[] args) {

System.out.println("买宝马");

Car bmw= CarFactory("BMW");

bmw.run();

System.out.println("买大奔");

Car benz= CarFactory("Benz");

benz.run();

}public staticCar CarFactory(String carName) {if ("BMW".equals(carName)) {return newBMW();

}else if ("Benz".equals(carName)) {return newBenz();

}else{throw new RuntimeException("车型有误");

}

}

}abstract classCar {public abstract voidrun();

}class BMW extendsCar {

@Overridepublic voidrun() {

System.out.println("BMW跑跑");

}

}class Benz extendsCar {

@Overridepublic voidrun() {

System.out.println("Benz跑跑");

}

}

模拟spring工厂:

importjava.io.BufferedReader;importjava.io.FileReader;importjava.io.IOException;importjava.lang.reflect.Constructor;importjava.lang.reflect.Field;classStudent{private intid;privateString name;public Student(intid , String name){this.id =id;this.name =name;

}publicStudent(){

}public intgetId() {returnid;

}public void setId(intid) {this.id =id;

}publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}

@OverridepublicString toString() {return this.id +"-"+this.name;

}

}classPerson{private intage;publicPerson(){

}

@OverridepublicString toString() {return this.age+"";

}

}public classDemo1 {public static void main(String[] args) throwsException {

Object o=getInstance();

System.out.println(o);

}public static Object getInstance() throwsException{

FileReader fileReader= new FileReader("src/info.txt");

BufferedReader bufferedReader= newBufferedReader(fileReader);

String line=bufferedReader.readLine();

Class clazz=Class.forName(line);

Constructor c= clazz.getConstructor(null);

Object c1= c.newInstance(null);while((line=bufferedReader.readLine())!=null){

String[] datas= line.split("=");

Field f= clazz.getDeclaredField(datas[0]);

f.setAccessible(true);if(f.getType()==int.class){

f.set(c1, Integer.parseInt(datas[1]));

}else{//f.setAccessible(true);

f.set(c1,datas[1]);

}

}returnc1;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值