11.多线程中的空指针问题
private void work() {
Log.d("zouhecan", getThreadId() + "start work()");
if (model != null) {
Log.d("zouhecan", getThreadId() + "id=" + model.getId());
Log.d("zouhecan", getThreadId() + "name=" + model.getName());//model throw NullPointerException
Log.d("zouhecan", getThreadId() + "flag=" + model.getFlag());
}
}
private Runnable workRunnable = new Runnable() {
@Override
public void run() {
try {
work();
Thread.sleep(1000);
} catch (Exception e) {
Log.e("zouhecan", e.getMessage());
}
}
};
private Runnable resetRunnable = new Runnable() {
@Override
public void run() {
Log.d("zouhecan", getThreadId() + "model=null");
model = null;
}
};
private synchronized void work() {
...
}
12.使用反射
try {
Class clazz = Class.forName("com.example.fragmenttest.TestClass");
testReflection(clazz);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//获取public构造函数
Constructor[] constructors = clazz.getConstructors();
//获取所有构造函数(public,private,protected)
Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
@SuppressWarnings("unchecked")
Constructor constructor = clazz.getDeclaredConstructor(String.class, int.class);
constructor.setAccessible(true);
TestClass testClass = (TestClass) constructor.newInstance("反射调用构造函数", 1);//创建对象
public class TestClass {
private TestClass(String message, int mode) {
Log.d("zouhecan", message);
}
...
}
private void testFields(Class clazz){
//获取public字段
Field[] fields = clazz.getFields();
//获取所有字段
Field[] declaredFields = clazz.getDeclaredFields();
for (Field field : fields) {
Log.d("zouhecan", field.getName());
}
for (Field field : declaredFields) {
Log.d("zouhecan", field.getName());
}
}
try {
TestClass instance = (TestClass) clazz.getConstructor().newInstance();
//反射设置filed值
Field numberField = clazz.getField("number");//number是public field
numberField.set(instance, 1);
//反射获取filed值
Field nameField = clazz.getDecarledField("name");//name是private field
nameField.setAccessible(true);//解除私有限制
String nameValue = (String) nameField.get(instance);
} catch (Exception e) {
e.printStackTrace();
}
反射调用method,与操作field类似,getMethods()获取public方法(包含父类public方法),getDeclaredMethods()获取全部方法(自己申明的,不包括继承的)。通过getMethod("methodName")获取指定方法名的方法(public),通过getDeclaredMethod("methodName")获取指定的非public方法。再创建类实例instance后,就可以通过method.invoke(instance)调用方法。如果方法是含参的,则在反射获取方法时,需要指明方法参数,method.getDeclaredMethod("method", Object.class),并在调用时指明实参method.invoke(instance, ‘params‘)。
@SuppressWarnings("unchecked") private void testMethod(Class clazz) { //获取public方法 Method[] methods = clazz.getMethods(); //获取全部方法 Method[] declaredMethods = clazz.getDeclaredMethods(); try { //创建实例 TestClass instance = (TestClass) clazz.getConstructor().newInstance(); //获取public方法 Method mTestReflect = clazz.getMethod("testReflect"); //获取非public方法 Method mInit = clazz.getDeclaredMethod("init"); //获取一个名为test,参数为string类型的方法 Method mTest = clazz.getDeclaredMethod("test", String.class); //调用方法 mTestReflect.invoke(instance); mInit.invoke(instance); mTest.invoke(instance, "test invoke method by reflect");//调用方法,并传入方法实参 } catch (InstantiationException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } }
1.定义常量
public class TestClass { //String 会被 JVM 优化 private final String FINAL_VALUE = "FINAL"; public String getFinalValue() { //剧透,会被优化为: return "FINAL" ,拭目以待吧 return FINAL_VALUE; } }
2.反射修改常量
/** * 修改对象私有常量的值 * 为简洁代码,在方法上抛出总的异常,实际开发别这样 */ private static void modifyFinalFiled() throws Exception { //1. 获取 Class 类实例 TestClass testClass = new TestClass(); Class mClass = testClass.getClass(); //2. 获取私有常量 Field finalField = mClass.getDeclaredField("FINAL_VALUE"); //3. 修改常量的值 if (finalField != null) { //获取私有常量的访问权 finalField.setAccessible(true); //调用 finalField 的 getter 方法 //输出 FINAL_VALUE 修改前的值 System.out.println("Before Modify:FINAL_VALUE = " + finalField.get(testClass)); //修改私有常量 finalField.set(testClass, "Modified"); //调用 finalField 的 getter 方法 //输出 FINAL_VALUE 修改后的值 System.out.println("After Modify:FINAL_VALUE = " + finalField.get(testClass)); //使用对象调用类的 getter 方法 //获取值并输出 System.out.println("Actually :FINAL_VALUE = " + testClass.getFinalValue()); } }
3.结果 Before Modify:FINAL_VALUE = FINAL After Modify:FINAL_VALUE = Modified Actually :FINAL_VALUE = FINAL
结果出来了:
第一句打印修改前 FINAL_VALUE
的值,没有异议;
第二句打印修改后常量的值,说明FINAL_VALUE
确实通过反射修改了;
第三句打印通过 getFinalValue()
方法获取的 FINAL_VALUE
的值,但还是初始值,导致修改无效!不信的话,看看字节码吧。
13.范型
14.注解自动生成器
15.坚持记录吧
原文:https://www.cnblogs.com/zhc-android-blogger/p/12939332.html