反射

Class对象

每个类加载到内存后都对应一个class对象

梅格雷有且只有一个class对象

 

保存类的信息的类称为class

Object 类中的 getClass( ) 方法将会返回一个 Class 类型的实例。

Employee e;
Class cl = e.getClass();
 
 
获取Class对象的3中方法
1、 
getName()方法将会返回类名
System.out.println(e.getClass().getName() + " " + e.getName());
Employee Harry Hacker
 
可以发现用class属性和getClass返回的输出是一样的,用getName返回的比前面两种少了class和一个空格
 
2、
还可以调用静态方法 forName 获得类名对应的 Class 对象。
String className = "java.util .Random";
Class cl = Class.forName(className);
如果类名保存在字符串中, 并可在运行中改变, 就可以使用这个方法。当然, 这个方法
只有在 className 是类名或接口名时才能够执行。否则,forName 方法将抛出一个 checked
exception ( 已检查异常)。无论何时使用这个方法, 都应该提供一个异常处理器
 
Class类中的 getFields、 getMethods 和 getConstructors 方 法 将 分 别 返 回 类 提 供 的
public 域、 方法和构造器数组, 其中包括超类的公有成员。Class 类的 getDeclareFields、
getDeclareMethods 和 getDeclaredConstructors 方法将分别返回类中声明的全部域、 方法和构
造器, 其中包括私有和受保护成员,但不包括超类的成员。
 
3、
获得 Class类对象的第三种方法非常简单。如果 T 是任意的 Java 类型(或 void 关键字,) T.class 将代表匹配的类对象。例如:
Class cl1 = Random.class; // if you import java.util
Cass cl2 = int.class;
Class cl3 = Double[].class;
 
 .newInstance() 使用forName和newInstance方法可以创建一个关于某个类的实例,且调用这个类的默认无参数构造器
 
 
• Field[] getFields() 1.1
• Filed[] getDeclaredFie1ds() 1
.1 getFields 方法将返回一个包含 Field 对象的数组, 这些对象记录了这个类或其超类的 公有域。getDeclaredField 方法也将返回包含 Field 对象的数组, 这些对象记录了这个 类的全部域。如果类中没有域, 或者 Class 对象描述的是基本类型或数组类型, 这些 方法将返回一个长度为 0 的数组。
• Method[] getMethods() 1.1
• Method[] getDeclareMethods() 1.1 返回包含 Method 对象的数组:getMethods 将返回所有的公有方法, 包括从超类继承 来的公有方法;getDeclaredMethods 返回这个类或接口的全部方法, 但不包括由超类 继承了的方法。
• Constructor;!] getConstructors() 1.1
• Constructor;] getDeclaredConstructors() 1.1 返回包含 Constructor 对象的数组, 其中包含了 Class 对象所描述的类的所有公有构造器(getConstructors) 或所有构造器(getDeclaredConstructors)。
 

获取无参构造,创建实例

package fanshe;

public class Person {
private String name;
private int age;
public Person() {
    
}
public Person(String aName,int aAge) {
    this.name=aName;
    this.age=aAge;
}
@Override
    public String toString() {
        // TODO Auto-generated method stub
        return "Person"+name+","+age;
    }
}



package fanshe;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Demo1 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//    1.获取类对象
    Class<?> class1 = Class.forName("fanshe.Person");
//    2.获取类的构造方法
//    Constructor<?>[] constructors = class1.getConstructors();
//    for(Constructor<?> constructor:constructors) {
//        System.out.println(constructor.toString());
//    }
//    3.获取类中的无参构造
    Constructor<?> constructor = class1.getConstructor();
    Person zhangsan = (Person)constructor.newInstance();
    System.out.println(zhangsan.toString());
//    简便方法
    Person wangwu = (Person)class1.newInstance();
    System.out.println(wangwu.toString());
//    4.获取类中的有参构造
    Constructor<?> constructor2 = class1.getConstructor(String.class,int.class);
    Person lisi = (Person)constructor2.newInstance("lisi",20);
    System.out.println(lisi.toString());
}
}
View Code

 

获取类内方法

package fanshe;

public class Person {
private String name;
private int age;
public Person() {
    
}
public Person(String aName,int aAge) {
    this.name=aName;
    this.age=aAge;
}
@Override
    public String toString() {
        // TODO Auto-generated method stub
        return "Person"+name+","+age;
    }
public void setName(String name){
    this.name = name;
}
public void setAge(int age){
    this.age=age;
}
public String getName(){
    return this.name;
}
public int getAge(){
    return this.age;
}
private void eat(String food){
    System.out.println(this.name+"在吃"+food);
}
public static void play(String other){
    System.out.println("跟"+other+"一起玩");
}
}



package fanshe;

import static org.junit.Assert.fail;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
public class Demo2 {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException, SecurityException, IllegalArgumentException {
//      获取class对象
      Class<?> class1 = Class.forName("fanshe.Person");
//      getMethods()获取公开的方法,包括从父类继承的方法
      Method[] methods = class1.getMethods();
      for (Method method:methods){
          System.out.println(method);
      }
//      getDeclaredMethods()获取类中的所有方法,包括私有的,不包括继承方法
      Method[] methods1 = class1.getDeclaredMethods();
      for(Method method:methods){
          System.out.println(method);
      }
//      1.获取单个方法
      Method setName = class1.getMethod("setName", String.class);
      Method getName = class1.getMethod("getName");
      Person zhangsan = (Person) class1.newInstance();
      setName.invoke(zhangsan,"zhangsan");
      String name = (String) getName.invoke(zhangsan);
      System.out.println(name);

      Constructor<?> constructor = class1.getConstructor(String.class,int.class);
      Person lisi = (Person) constructor.newInstance("lisi",22);
      String name2 = (String) getName.invoke(lisi);
      System.out.println(name2);
//      2.获取私有方法
      Method privateMethod = class1.getDeclaredMethod("eat",String.class);
//      设置访问权限无效
      privateMethod.setAccessible(true);
      privateMethod.invoke(lisi,"面包");
//      3.获取静态方法
      Method staticMethod = class1.getMethod("play", String.class);
      staticMethod.invoke(class1,"xiaoming");
      
      Properties properties = new Properties();
      invokeAny(properties, "setProperty", new Class[] {String.class,String.class}, "username","zhangsan");
      System.out.println(properties.toString());
      
      reflectOpe();
  }
//    4.使用反射实现一个可以调用任何对象方法的通用方法
    public static Object invokeAny(Object object ,String methodname,Class<?>[] types,Object...args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        Class<?> class1 = object.getClass();
        Method method = class1.getMethod(methodname,types);
        return method.invoke(object, args);
    }
//    5.使用反射获取类中的属性
    public static void reflectOpe() throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException {
        Class<?> class1 = Class.forName("fanshe.Person");
//        获取属性公开的字段,父类继承的字段
        Field[] fields = class1.getFields();
        System.out.println(fields.length);
//        获取所有的属性,包括私有,默认,包含
        Field[] fields2 = class1.getDeclaredFields();
        System.out.println(fields2.length);
        for (Field field:fields2) {
            System.out.println(field);
        }
//        获取name属性
        Field name = class1.getDeclaredField("name");
        Person liwu = (Person)class1.newInstance();
//        赋值
        name.setAccessible(true);
        name.set(liwu, "liwu");
//        获取值
        System.out.println(name.get(liwu));
    }
    
}
View Code

 

 工厂模式

package factory_Demo;

public interface Usb {
public void service();
}


package factory_Demo;

public class Upan implements Usb{
@Override
public void service() {
    System.out.println("Upan开始执行");
}
}


package factory_Demo;

public class Keyboard implements Usb{
@Override
public void service() {
    System.out.println("keyboard开始执行");
}
}


package factory_Demo;

public class Mouse implements Usb{
@Override
public void service() {
    System.out.println("mouse开始执行");
}
}


package factory_Demo;

public class Fan implements Usb{
@Override
public void service() {
    System.out.println("fan开始执行");
}
}


1=factory_Demo.Mouse
2=factory_Demo.Fan
3=factory_Demo.Upan
4=factory_Demo.Keyboard


package factory_Demo;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

public class UsbFactory {
public static Usb createUsb(String type) {
    Usb usb = null;
    Class<?> usbclass = null;
    try {
        usbclass = Class.forName(type);
        usb = (Usb)usbclass.newInstance();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        System.out.println(e.getMessage());
    }
    return usb;
}
}



package factory_Demo;

import java.io.FileInputStream;
import java.util.Properties;
import java.util.Scanner;

public class Demo {
public static void main(String[] args) throws Exception{
    Scanner scanner = new Scanner(System.in);
    System.out.println("请输入类型:");
    String input = scanner.nextLine();
    Properties properties = new Properties();
    FileInputStream inputStream = new FileInputStream("src\\factory_Demo\\UsbFactory.properties");
    properties.load(inputStream);
    inputStream.close();
    Usb usb = UsbFactory.createUsb(properties.getProperty(input));
    if(usb!=null) {
        System.out.println("购买成功");
        usb.service();
    }else {
        System.out.println("购买失败,你要的产品不存在");
    }
}
}
View Code

 

 饿汉式单例

package factory_Demo;

public class SingleTon {
private static final SingleTon instance = new SingleTon();
private SingleTon() {
}
public static SingleTon getSingleTon() {
    return instance;
}
}


package factory_Demo;

public class TestSingleTon {
public static void main(String[] args) {
    for(int i=0;i<3;i++) {
        new Thread(new Runnable() {
            
            @Override
            public void run() {
                System.out.println(SingleTon.getSingleTon().hashCode());
            }
        }).start();;
    }
}
}
View Code

 

 懒汉式单例

package factory_Demo;

import javax.management.InstanceAlreadyExistsException;

public class SingleTon2 {
private static SingleTon2 instance = null;
private SingleTon2() {};
public static SingleTon2 getInstance() {
    if (instance==null) {
    synchronized (SingleTon2.class) {
        if(instance==null) {
            instance = new SingleTon2();
        }
    }
    }
    return instance;
}
}


package factory_Demo;

public class TestSingleTon {
public static void main(String[] args) {
    for(int i=0;i<3;i++) {
        new Thread(new Runnable() {
            
            @Override
            public void run() {
                System.out.println(SingleTon2.getInstance().hashCode());
            }
        }).start();;
    }
}
}
View Code

懒汉式另一种写法

package factory_Demo;

public class SingleTon3 {
private SingleTon3() {};
private static class Sing{
    static SingleTon3 singleTon3 = new SingleTon3();
}
public static SingleTon3 getInstance() {
    return Sing.singleTon3;
}
}
View Code 

 

2种类型的优缺点

饿汉式:优点:线程安全  缺点:生命周期长,浪费空间

懒汉式:优点:生命周期短,节省空间  缺点:线程安全问题

 

 

 

 

 

 
posted @ 2019-08-13 22:19  hjj123  阅读(77)  评论(0)    收藏  举报