反射
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()); } }
获取类内方法
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)); } }
工厂模式
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("购买失败,你要的产品不存在"); } } }
饿汉式单例
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();; } } }
懒汉式单例
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();; } } }
懒汉式另一种写法
package factory_Demo; public class SingleTon3 { private SingleTon3() {}; private static class Sing{ static SingleTon3 singleTon3 = new SingleTon3(); } public static SingleTon3 getInstance() { return Sing.singleTon3; } }
2种类型的优缺点
饿汉式:优点:线程安全 缺点:生命周期长,浪费空间
懒汉式:优点:生命周期短,节省空间 缺点:线程安全问题
浙公网安备 33010602011771号