标签:垃圾回收 原因 public dep 理解 ati 泛型使用 protect nat
反射的基本概念
如果正常的情况下,如果使用一个类,则必须按照如下的步骤操作:
反射过程不需要有明确类型的对象,所有的对象使用Object表示
1. 可以直接使用Object与反射机制的混合调用类中的方法。
Object类中的所有方法以及每一个方法使用上的注意事项:
在printStream类中找到print输出方法 如下
public void print(Object obj) {
write(String.valueOf(obj));
}
可以看到他在输出的时候调用了String的valueOf方法,下面打开valueOf方法源码
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}从中我们可以看到如果传入的对象不为null的话就会自动的调用toString()方法然后返回
Object
的运行时类。
notify()
方法或notifyAll()
方法。 换句话说,这个方法的行为就好像简单地执行调用wait(0)
。
notify()
或者notifyAll()方法来唤醒线程;
Class类
class类是整个反射的操作源头,而类的定义如下:
public final class Class<T> //反射的泛型几乎无用,使用的时候就使用“?” extends Object implements Serializable, GenericDeclaration, Type, AnnotatedElement
如果想要使用Class类进行操作,那么必须首先产生Class类的实例化对象,而有三种方法可以去的Claas类的实例化对象
Class
对象。如果是程序设计人员,使用最多的方法一定是forName()方法,但是如果是使用者会使用“类.class”。工厂设计模式最好利用反射机制来解决耦合问题。
利用反射实例化对象
Class类如果使用了forName()方法之后,就可以使用Class类定义的newInstance()方法默认去调用类之中的无参构造器进行操作
public T newInstance?() throws InstantiationException, IllegalAccessException,此泛型使用不到
代码演示: 在这里是不能接受的了这个返回值的,
这里就是解决上面错误的代码实现: 从中我们就可以看到我们不一定非要使用new实例化对象,只要我们有一个类的完整名称也可以实例化对象
public class R { public static void main(String[] args) throws Exception { Class<?> cls = Class.forName("test.Student"); //jdk 1.9 开始直接使用的newInstance()方法已经过时,可以使用下面的方式来调用newInstance()方法 //相当于关键字new实例化对象。等价于 Object newInstance = new Student(); Object newInstance = cls.getDeclaredConstructor().newInstance(); } } class Student{ public Student() { System.out.println("构造方法Student"); } }
执行结果:构造方法Student
但是如果使用反射实例化对象,必须要求类中存在有无参构造方法,因为newInstance()方法只能找到无参。如果没有无参构造函数如下:
Exception in thread "main" java.lang.NoSuchMethodException:
如果想找到无参构造怎么办?操作构造方法
操作构造方法:
为了解决NoSuchMethodException错误,这个时候这能取得类之中的构造方法,传递所需要的参数后才能使用。
在Class类里面定义了可以取得一个类中的构造方法的操作:
throws NoSuchMethodException, SecurityException
Constructor
对象,及时取得类中制定参数的构造,该对象反映由此Class
对象表示的类的指定公共构造函数。public Class<?>[] getDeclaredClasses?()
throws SecurityException
Class
对象的数组,就是全部构造,反映了所有被声明为由这个Class
对象表示的类的成员的类和接口。代码演示:取得String中的全部构造方法。
import java.lang.reflect.Constructor; public class GetStringConstructor { public static void main(String[] args) throws Exception { Class<?> forName = Class.forName("java.lang.String"); Constructor<?>[] constructors = forName.getConstructors();//得到所有构造 for (int i = 0; i < constructors.length; i++) { System.out.println(constructors[i]); } } }
执行结果:
public java.lang.String(byte[])
public java.lang.String(byte[],int,int)
public java.lang.String(byte[],java.nio.charset.Charset)
public java.lang.String(byte[],java.lang.String) throws java.io.UnsupportedEncodingException
public java.lang.String(byte[],int,int,java.nio.charset.Charset)
public java.lang.String(java.lang.StringBuilder)
public java.lang.String(java.lang.StringBuffer)
public java.lang.String(char[],int,int)
public java.lang.String(char[])
public java.lang.String(java.lang.String)
public java.lang.String()
public java.lang.String(byte[],int,int,java.lang.String) throws java.io.UnsupportedEncodingException
public java.lang.String(byte[],int)
public java.lang.String(byte[],int,int,int)
public java.lang.String(int[],int,int
所以如果现在想要进行制定构造方法的调用,就必须将关注点放在Contructor类中。
public T newInstance?(Object... initargs) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException 使用由此Constructor
对象表示的构造函数,使用指定的初始化参数创建和初始化构造函数的声明类的新实例。
代码实现:实例化刚才的Student对象
import java.lang.reflect.Constructor;
class Student{
public Student(String str) {
System.out.println("构造方法Student: "+str);
}
} public class GetStringConstructor { public static void main(String[] args) throws Exception { Class<?> forName = Class.forName("test.Student"); Constructor<?> constructors = forName.getConstructor(String.class);//从这可以看到要与想调用的构造方法的参数类型一直才可以 constructors.newInstance("纯菜鸟-java-反射"); } }
执行结果:构造方法Student: 纯菜鸟-java-反射 time:40.00
分析简单java类与反射的联系
利用反射解决servlet代码过多的问题
用反射来解决工厂模式,代理设计模式的操作
动态代理设计模式,CGLIB实现的动态代理设计模式
使用Annotion编写注解操作
标签:垃圾回收 原因 public dep 理解 ati 泛型使用 protect nat
原文地址:http://www.cnblogs.com/wzqjy/p/7816673.html