首先说一下获取类名称的几种方式
package org.java;
/**
* @author yangkun
* @date 2021-04-07
*/
public class Reflect {
public static void main(String[] args) {
Class<? extends Object> c1 = Reflect.class;
System.out.println(c1.getName());
Reflect reflect = new Reflect();
Class<? extends Reflect> c2 = reflect.getClass();
System.out.println(c2.getName());
try {
Class<Reflect> c3 = (Class<Reflect>) Class.forName("org.java.Reflect");
System.out.println(c3.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
获取成员方法
//获取该类的所有方法但是不包括父类的方法
public Method getDeclaredMethod(String name,Class<?>...paramterTypes);
//获取该类以及父类的所有public方法
public Method getMethod(String name,Class<?>...paramterTypes)
package org.java;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @author yangkun
* @date 2021-04-07
*/
public class Person {
private String name="crossover" ;
private String msg ;
public Person(String name, String msg) {
this.name = name;
this.msg = msg;
System.out.println(name+"的描述是"+msg);
}
public Person() {
super();
}
public void say(String name ,String msg){
System.out.println(name+"说:"+msg);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public static void main(String[] args) {
try {
//首先获取类类型
Class p1 =Class.forName("org.java.Person");
//通过newInstance()方法生成一个实例
Object o1 = p1.newInstance();
//获取该类的say方法
Method m1 = p1.getMethod("say", String.class, String.class);
//通过invoke方法调用该方法
m1.invoke(o1,"张三","你好啊");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
结果输出:
张三说:你好啊
获取成员变量
1.public Field getDeclaredFiled(String name)//获得该类所有的成员变量,但不包括父类的。
2.public Filed getFiled(String name)//获得该类的所有的public变量,包括其父类的。
public static void main(String[] args) {
try {
Class c1 = Class.forName("org.java.Person");
Field field = c1.getDeclaredField("name");
Object o1 = c1.newInstance();
/**
* 由于Person类中的name变量是private修饰的,
* 所以需要手动开启允许访问,是public修饰的就不需要设置了
*/
field.setAccessible(true);
Object name = field.get(o1);
System.out.println(name);
} catch (Exception e) {
e.printStackTrace();
}
}
获取构造方法
1.public Constructor getDeclaredConstructor(Class<?>...parameterTypes)//获取该类的所有构造方法,不包括父类的。
2.public Constructor getConstructor(Class<?>...parameterTypes)//获取该类的所有public修饰的构造方法,包括父类的。
在之前的Person类中有以下的构造方法:
public Person(String name, String msg) {
this.name = name;
this.msg = msg;
}
我们可以通过以下方法来获取Person类的构造方法:
Constructor dc1 = c1.getDeclaredConstructor(String.class,String.class) ;
具体代码如下:
Constructor dc1 = c1.getDeclaredConstructor(String.class,String.class) ;
dc1.setAccessible(true);
dc1.newInstance("小明","很帅") ;
dc1.newInstance(“小明”,“很帅”);
方法调用了Person类中的:
public Person(String name, String msg) {
this.name = name;
this.msg = msg;
System.out.println(name+"的描述是"+msg);
}
这个构造方法,如果不传参数的话,那么调用的就是无参的构造方法。
输出结果为:
小明的描述是很帅
通过反射了解集合泛形的本质
package org.java;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* @author yangkun
* @date 2021-04-07
*/
public class GenericIssue {
public static void main(String[] args) {
List list1 = new ArrayList();
List<String> list2 = new ArrayList<String>();
list2.add("你好");
// list2.add(11) ;加上泛型之后在编译期间只能添加String,不然会报错。
System.out.println("list2的长度是:"+list2.size());
Class c1 = list1.getClass();
Class c2 = list2.getClass();
System.out.print("c1,c2是否相等:");
System.out.println(c1==c2);
try {
Method method = c2.getDeclaredMethod("add", Object.class);
//在这里加入int类型,在上面如果加入int会出现编译报错。
method.invoke(list2, 123) ;
//list2的长度增加了,说明添加成功了
System.out.println("现在list2的长度是:"+list2.size());
/**
* 所以可以看出,泛型只是在编译期间起作用,在经过编译进入运行期间是不起作用的。
* 就算不是泛型要求的类型也是可以插入的。
*/
} catch (Exception e) {
e.printStackTrace();
}
}
}