反射实践代码
过反射获取类的实例
package com.njlife123.qzmall.base;
public class Q {
int a = 2;
int b = 2;
public Q() {
}
public Q(int a) {
this.a = a;
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
}
package com.njlife123.qzmall.base;
public class Test5 {
public static void main(String[] args) throws Exception {
//包名.类名
Class<?> aClass = Class.forName("com.njlife123.qzmall.base.Q");
//强转成Q类
Q q = (Q)aClass.newInstance();
}
}
获取类属性信息
package com.njlife123.qzmall.base;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class Test5 {
public static void main(String[] args) throws Exception {
//包名.类名
Class<?> aClass = Class.forName("com.njlife123.qzmall.base.Q");
Field[] fields = aClass.getDeclaredFields();//获取属性信息
for (int i=0;i<fields.length;i++){
Field field = fields[i];
//判断是否是私有
if(field.isAccessible()){
field.setAccessible(false);
}
System.out.println("属性名: "+ field.getName());
System.out.println("属性类型: "+ field.getType());
System.out.println("属性值: "+ field.get(aClass.newInstance()));
System.out.println("访问修饰符: "+ Modifier.toString(field.getModifiers()));
}
}
}
```java
打印结果:
属性名: a
属性类型: int
属性值: 2
访问修饰符:
属性名: b
属性类型: int
属性值: 2
访问修饰符:
Process finished with exit code 0
获得类的方法信息
package com.njlife123.qzmall.base;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Test5 {
public static void main(String[] args) throws Exception {
//包名.类名
Class<?> aClass = Class.forName("com.njlife123.qzmall.base.Q");
Method[] declaredMethods = aClass.getDeclaredMethods();
for (Method method : declaredMethods){
System.out.println("方法名: "+ method.getName());
System.out.println("返回类型: "+method.getReturnType());
System.out.println("访问修饰符: "+ Modifier.toString(method.getModifiers()));
//参数类型class数组
Class<?>[] parameterTypes = method.getParameterTypes();
if(parameterTypes.length > 0){
for (Class c : parameterTypes){
System.out.print(c);
}
}
System.out.println();
}
}
}
打印结果:
方法名: getA
返回类型: int
访问修饰符: public
方法名: setA
返回类型: void
访问修饰符: public
int
Process finished with exit code 0
获得类的构造函数信息
package com.njlife123.qzmall.base;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Test5 {
public static void main(String[] args) throws Exception {
//包名.类名
Class<?> aClass = Class.forName("com.njlife123.qzmall.base.Q");
Constructor<?>[] constructors = aClass.getConstructors();
for (Constructor c : constructors){
System.out.println("名字:"+c.getName());
System.out.println("访问修饰符:"+ Modifier.toString(c.getModifiers()));
//获取参数类型class数组
Class[] parameterTypes = c.getParameterTypes();
if(parameterTypes.length > 0){
for (Class clz : parameterTypes){
System.out.println(clz);
}
}
System.out.println();
}
}
}
打印结果:
名字:com.njlife123.qzmall.base.Q
访问修饰符:public
名字:com.njlife123.qzmall.base.Q
访问修饰符:public
int
Process finished with exit code 0
修改类的属性
package com.njlife123.qzmall.base;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Test5 {
public static void main(String[] args) throws Exception {
//包名.类名
Class<?> aClass = Class.forName("com.njlife123.qzmall.base.Q");
//getField只获取public修饰属性
Field a = aClass.getField("a");
Q q = (Q)aClass.newInstance();
a.set(q,33);
System.out.println(q.a);
}
}
打印结果:
33
Process finished with exit code 0
调用类的方法
package com.njlife123.qzmall.base;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Test5 {
public static void main(String[] args) throws Exception {
//包名.类名
Class<?> aClass = Class.forName("com.njlife123.qzmall.base.Q");
Q q = (Q)aClass.newInstance();
Method setA = aClass.getDeclaredMethod("setA", int.class);//setA参数int
Method getA = aClass.getDeclaredMethod("getA", null);//无参数null
setA.invoke(q,123);
getA.invoke(q);
}
}
Q类:
public int getA() {
System.out.println("getA");
return a;
}
public void setA(int a) {
System.out.println("setA");
this.a = a;
}
调用类的构造函数
package com.njlife123.qzmall.base;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Test5 {
public static void main(String[] args) throws Exception {
//包名.类名
Class<?> aClass = Class.forName("com.njlife123.qzmall.base.Q");
//空参构造
Constructor<?> constructor = aClass.getConstructor();
//有参数构造 传参Class<?>... parameterTypes ,三点表示传参是数组
Class [] c = {int.class};
Constructor<?> constructor1 = aClass.getConstructor(c);
//也可以这样写,比如构造器参数为int和String
// aClass.getConstructor(int.class,String.class);
Q q = (Q)constructor.newInstance();
Q q1 = (Q)constructor1.newInstance(22);
System.out.println(q);
System.out.println(q1);
}
}
打印结果:
空参构造
参数int a构造
com.njlife123.qzmall.base.Q@2f2c9b19
com.njlife123.qzmall.base.Q@31befd9f
Process finished with exit code 0
线程
Java中线程的状态分为6种。
- 初始(NEW):新创建了一个线程对象,但还没有调用start()方法。
- 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。
线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。 - 阻塞(BLOCKED):表示线程阻塞于锁。
状态不同于WAITING,它可以在指定的时间后自行返回。等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。
5. 超时等待(TIMED_WAITING):该
6. 终止(TERMINATED):表示该线程已经执行完毕。
这6种状态定义在Thread类的State枚举中,可查看源码进行一一对应。
线程的状态图
- 初始状态
实现Runnable接口和继承Thread可以得到一个线程类,new一个实例出来,线程就进入了初始状态。
2.1. 就绪状态
就绪状态只是说你资格运行,调度程序没有挑选到你,你就永远是就绪状态。
调用线程的start()方法,此线程进入就绪状态。
当前线程sleep()方法结束,其他线程join()结束,等待用户输入完毕,某个线程拿到对象锁,这些线程也将进入就绪状态。
当前线程时间片用完了,调用当前线程的yield()方法,当前线程进入就绪状态。
锁池里的线程拿到对象锁后,进入就绪状态。
2.2. 运行中状态
线程调度程序从可运行池中选择一个线程作为当前线程时线程所处的状态。这也是线程进入运行状态的唯一一种方式。
- 阻塞状态
阻塞状态是线程阻塞在进入synchronized关键字修饰的方法或代码块(获取锁)时的状态。
- 等待
处于这种状态的线程不会被分配CPU执行时间,它们要等待被显式地唤醒,否则会处于无限期等待的状态。
- 超时等待
处于这种状态的线程不会被分配CPU执行时间,不过无须无限期等待被其他线程显示地唤醒,在达到一定时间后它们会自动唤醒。
- 终止状态
当线程的run()方法完成时,或者主线程的main()方法完成时,我们就认为它终止了。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦终止了,就不能复生。
在一个终止的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。
等待队列
调用obj的wait(), notify()方法前,必须获得obj锁,也就是必须写在synchronized(obj) 代码段内。