反射
Java中编译类型有两种:
反射Class的使用
Person p1 = new Person();
// 1 对象的getClass方法
Class c1 = p1.getClass();
System.out.println(c1);
// 2 类的class属性
System.out.println(Person.class);
// 3 Class.forName
try {
Class c = Class.forName("Person");
System.out.println(c);
Field f = c.getField("age");
System.out.println(f);
}catch (Error e){
e.printStackTrace();
}
Test test = new Test();
Class c4 = test.getClass();
// 获取类的名字
String className =c4.getName();
System.out.println(className);
// 获取所有public的字段
List fieldsPublic = Arrays.asList(c.getFields());
System.out.println(fieldsPublic);
// 获取所有字段
List fieldsAll = Arrays.asList(c.getDeclaredFields());
System.out.println(fieldsAll);
// 获得类的public类型的方法 包含继承下来的
Method[] methods = c.getMethods();
// 获取类自己的,所有声明的方法
Method[] methods = c.getDeclaredMethods();
// 获取指定名字的方法
Method method = c.getMethod("gg");
System.out.println(method);
Constructor[] constructors;
// 获取类的所有构造方法,是一个数组,因为构造方法不止一个
constructors = c4.getDeclaredConstructors();
// 索引为1的构造方法
Constructor c1 = constructors[1];
System.out.println(c1);
// 构造方法的修饰符
System.out.println(Modifier.toString(c1.getModifiers()));
// 构造方法的参数
Class[] args1 = c1.getParameterTypes();
System.out.println(args1[0]);
// 获取指定构造方法并执行
Class[] p = {int.class, String.class};
constructors = c4.getDeclaredConstructor(p);
// 通过类的不带参数的构造方法创建这个类的一个对象
constructors.newInstance("huahua", 12);
代理
public class Proxy1 {
public static void main(String[] args) {
// 创建明星对象
IStar ldh = new LDHStar();
ProxyManger proxy = new ProxyManger(ldh);
proxy.sing();
}
}
interface IStar {
void sing();
}
// 真实对象
class LDHStar implements IStar {
@Override
public void sing() {
System.out.println("刘德华唱歌");
}
}
// 代理类需要有真实对象的控制权 (引用)
class ProxyManger implements IStar {
// 真实对象的引用
private IStar star;
public ProxyManger() {
super();
}
public ProxyManger(IStar star) {
super();
this.star = star;
}
@Override
public void sing(){
System.out.println("唱歌准备");
star.sing();
System.out.println("唱完了");
}
}
原文地址
枚举
public class enum1 {
public static void main(String[] args) {
Color c = Color.BLANK;
System.out.println(c);
System.out.println(c.getIndex());
System.out.println(c.getName());
}
}
enum Color {
RED("红色", 1),
GREEN("绿色", 2),
BLANK("白色", 3),
YELLO("黄色", 4),
PURPLE("粉色", 5);
// 成员变量
private String name;
private int index;
// 构造方法
Color(String name, int index) {
this.name = name;
this.index = index;
}
// 普通方法
public static String getName(int index) {
for (Color c : Color.values()) {
if (c.getIndex() == index) {
return c.name;
}
}
return null;
}
// get set 方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
//覆盖方法
@Override
public String toString() {
return this.index+"_"+this.name;
}
}
泛型
// 泛型类
class Foo<T> {
private T name;
Foo(T name){
this.name = name;
}
public T getName() {
return name;
}
}
interface jiekou1<T> {
T getName();
}
// 接口使用了泛型,类必须要用
class lei1<T> implements jiekou1<T>{
@Override
public T getName() {
return null;
}
}
public static void main(String[] args) {
Generic<Integer> gInteger = new Generic<Integer>(123);
Generic<Number> gNumber = new Generic<Number>(456);
showKeyValue1(gNumber);
showKeyValue1(gInteger);//报错
}
static void showKeyValue1(Generic<Number> obj){
System.out.println(obj.getKey());
}
// 把参数的类型,变成? 就成了类型通配符
static void showKeyValue1(Generic<?> obj){
System.out.println(obj.getKey());
}
// 泛型方法和可变参数
public static <T> void printMsg( T... args){
for(T t : args){
System.out.println("泛型测试" + "t is " + t);
}
}
// 只能是Number子类的数据
public void showKeyValue1(Generic<? extends Number> obj){
Log.d("泛型测试","key value is " + obj.getKey());
}
class Generic<T extends Number>{
//key这个成员变量的类型为T,T的类型由外部指定
private T key;
public Generic(T key) { //泛型构造方法形参key的类型也为T,T的类型由外部指定
this.key = key;
}
public T getKey(){ //泛型方法getKey的返回值类型为T,T的类型由外部指定
return key;
}
}
数组泛型
List<?>[] list = new ArrayList<?>[10];
ArrayList<String> list1 = new ArrayList<String>();
ArrayList<Integer> list2 = new ArrayList<Integer>();
list[0] = list1;
list[1] = list2;
list1.add("haha");
System.out.println(list[0]);
多线程
进程的特点
并行和并发
java线程的实现
public class Thread1 {
public static void main(String[] args) {
MyThread t = new MyThread("线程-1 ");
t.run();
}
}
class MyThread extends Thread {
private String name;
public MyThread(String name1) {
this.name = name1;
}
@Override
public void run() {
int a = 4;
while(--a > 0){
System.out.println(this.name + a);
}
}
};
public class Thread1 {
public static void main(String[] args) {
MyThread mt1 = new MyThread("线程A ") ; // 实例化对象
MyThread mt2 = new MyThread("线程B ") ; // 实例化对象
Thread t1 = new Thread(mt1) ; // 实例化Thread类对象
Thread t2 = new Thread(mt2) ; // 实例化Thread类对象
t1.start() ; // 启动多线程
t2.start() ; // 启动多线程
}
}
class MyThread implements Runnable{ // 实现Runnable接口,作为线程的实现类
private String name ; // 表示线程的名称
public MyThread(String name){
this.name = name ; // 通过构造方法配置name属性
}
@Override
public void run(){ // 覆写run()方法,作为线程 的操作主体
for(int i=0;i<10;i++){
System.out.println(name + "运行,i = " + i) ;
}
}
};
线程的生命周期
note
synchronized
synchronized(object) {
}
表示线程在执行的时候会对object对象上锁
wait与notify
死锁
当多个并发的线程分别试图同时占有两个锁时,会出现加锁冲突的情形。如果一个线程占有了另一个线程必需的锁,互相等待时被阻塞就有可能出现死锁
ThreadLocal
- ThreadLocal是除了加锁这种同步方式之外的,一种保证一种规避多线程访问出现线程不安全的方法,
- 当我们在创建一个变量后,如果每个线程对其进行访问的时候访问的都是线程自己的变量这样就不会存在线程不安全问题
- ThreadLocal不继承,InheritableThreadLocal可以继承
public class ThreadLocalTest {
static ThreadLocal<String> localVar = new ThreadLocal<>();
static void print(String str) {
//打印当前线程中本地内存中本地变量的值
System.out.println(str + " :" + localVar.get());
//清除本地内存中的本地变量
localVar.remove();
}
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
//设置线程1中本地变量的值
localVar.set("localVar1");
//调用打印方法
print("thread1");
//打印本地变量
System.out.println("after remove : " + localVar.get());
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
//设置线程1中本地变量的值
localVar.set("localVar2");
//调用打印方法
print("thread2");
//打印本地变量
System.out.println("after remove : " + localVar.get());
}
});
t1.start();
t2.start();
}
}
共有条评论 网友评论