1 类初始化的时机
class Temp{
static{
System.out.println("执行Temp初始化代码块");
}
}
public class TextDemo_02 {
public static void main(String[] args){
System.out.println("执行ClassLoader的loadClass方法");
ClassLoader classLoader=ClassLoader.getSystemClassLoader();
try {
classLoader.loadClass("Temp");//如果出现无法加载类的情况下,可能使不同的包有相同的类名,添加类的全限定名即可。
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("结束执行ClassLoader的loadClass方法");
System.out.println("------------分割线--------------");
System.out.println("开始执行Class的forName方法");
try {
Class.forName("Temp");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("结束执行Class的forName方法");
}
}
使用ClassLoader类的loadClass()方法来加载某个类时,该方法只加载该类,不会执行该类的初始化代码块,但是使用Class的forName()时会强制初始化该类
2创建对象
方法一:通过Class的newInstance方法创建对象
/**
* 存放类名对应的对象
*/
private static Map<String, Object> mapStrObj = new HashMap<String, Object>();
private static String a;
private static String b;
// 初始化类名
static {
// 加载配置文件
Properties pp = new Properties();
InputStream inputStrea = Object.class
.getResourceAsStream("/object.properties");
try {
pp.load(inputStrea);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 读取配置文件中的信息
a = pp.getProperty("a");
b = pp.getProperty("b");
}
public TextDemo_02() {
// TODO Auto-generated constructor stub
System.out.println("正在执行TextDemo_02的构造方法,正在创建TextDemo_02对象");
}
/**
* 生成对象
* @throws InstantiationException
* @throws IllegalAccessException
* @throws ClassNotFoundException
*/
public static void createObject() throws InstantiationException,
IllegalAccessException, ClassNotFoundException {
// 创建对象并添加到map中
Class<?> classA = Class.forName(a);
mapStrObj.put(a, classA.newInstance());
Class<?> classB = Class.forName(b);
mapStrObj.put(b, classB.newInstance());
}
public static void main(String[] args) {
try {
TextDemo_02.createObject();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mapStrObj.get("TextDemo_02");
}
object.properties文件中的信息:
a=TextDemo_01
b=TextDemo_02
方法二 :通过Constructor对象的newInstance方法来创建对象
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* 创建对象的第二种方法:调用Constructor的newInstance方法
*
* @author Shipp
*
*/
public class TextDemo_03 {
/**
* 定义一个构造方法
*
* @param str
*/
public TextDemo_03(String str) {
System.out.println("TextDemo_03有参构造方法传的参数:" + str);
System.out.println("正在执行TextDemo_03构造函数,正在创建TextDemo_03对象");
}
/**
* 创建对象
*
* @throws ClassNotFoundException
* @throws NoSuchMethodException
* @throws RuntimeException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static void createObject() throws ClassNotFoundException,
NoSuchMethodException, RuntimeException, InstantiationException,
IllegalAccessException, InvocationTargetException {
Class<?> class1 = Class.forName("TextDemo_03");// 根据类名获取对象
Constructor constructor = class1.getConstructor(String.class);// 获取类中一个带字符串的构造方法
Object obj = constructor.newInstance("创建对象");// 创建对象
}
public static void main(String[] args) {
try {
TextDemo_03.createObject();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RuntimeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
3 调用方法
/**
* 被调用的方法
* @param str
*/
public static void runMethod(String str){
System.out.println("正在执行TextDemo_02的runMethod方法,参数值为"+str);
}
/**
* 执行调用参数
* @throws NoSuchMethodException
* @throws SecurityException
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
*/
public static void invokingMethod() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
//获取对象
Object object=mapStrObj.get("TextDemo_02");
//获取实现类所对应的Class对象
Class<?> tarClass=object.getClass();
//获取希望调用的方法,第一个参数是方法名,从第二个参数开始是对应的形参类型
Method method=tarClass.getMethod("runMethod",String.class);
//执行调用,第一个参数是对象,第二个参数是要传的实参
method.invoke(object, "传递进去的参数");
}
4 获取和修改成员变量值
@Test
public void test03() throws NoSuchFieldException, IllegalAccessException {
class User{
private String userName;
public User(String userName) {
this.userName = userName;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
//获取对象中指定字段的值
Field field = User.class.getDeclaredField("userName");
field.setAccessible(true);
Object o = field.get(new User("u1"));
System.out.println(o);
//修改对象中指定字段的值
User u2 = new User("u2");
field.set(u2, "u3");
System.out.println(JSON.toJSONString(u2));
}
getDeclaredField是可以获取一个类的public字段.,getField只能获取类的所有 字段.
5操作数组
//创建元素类型为String类型 长10的数组
Object object=Array.newInstance(String.class,10);
//为数组中赋值,第一个参数为操作的对象,第二个参数为设置值的索引,第三个参数为值
Array.set(object, 0, "0");
Array.set(object, 1, "1");
//从数组中取数据,第一个参数为操作的对象,第二个为索引
Object object0=Array.get(object, 0);
Object object1=Array.get(object, 1);
System.out.println(object0);
System.out.println(object1);
Object object=Array.newInstance(String.class,10);
//为数组中赋值,第一个参数为操作的对象,第二个参数为设置值的索引,第三个参数为值
Array.set(object, 0, "0");
Array.set(object, 1, "1");
//从数组中取数据,第一个参数为操作的对象,第二个为索引
Object object0=Array.get(object, 0);
Object object1=Array.get(object, 1);
System.out.println(object0);
System.out.println(object1);
执行结果:
java.lang.ClassNotFoundException: TextDemo_03
因为你用的不是全类名,虚拟机是根据全类名(包名.类名)寻找相应的程序的
参考博客:https://zhidao.baidu.com/question/431605041629845604.html
实际应用:判断对象中部分字段是否全不为空
public static boolean isObjFieldNull(Object obj, List<String> checkFieldList) {
Field[] fields = obj.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
if (!checkFieldList.contains(field.getName())) {
continue;
}
Object fieldValue;
try {
fieldValue = field.get(obj);
} catch (IllegalAccessException e) {
System.out.println("获取对象字段值异常:" + e.getMessage());
continue;
}
if (fieldValue == null) {
return true;
}
if (fieldValue instanceof String) {
if (((String) fieldValue).length() == 0) {
return true;
}
}
}
return false;
}