类的对象,基于某个类 new 出来的对象,也称为实例对象。
类对象,类加载的产物,封装了一个类的所有信息(类名、父类、接口、属性、方法、构造方法)。
通过反射获取类对象。
// 通过类的对象,获取类对象
Student s = new Student();
Class c = s.getClass();
// 通过类名获取类对象
Class c = 类名.class;
// 通过静态方法获取类对象
Class c=Class.forName(“包名.类名”);
通过类对象获取类信息。
// Person 类
public class Person implements Serializable {
private String name;
int age;
public Person() {
// TODO Auto-generated constructor stub
}
public String getName() {
return name;
}
public void hello(String name,int age) {
System.out.println(name+"--->"+age);
}
}
public class Test {
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
// 反射对象
Class c1 = Person.class;
// 全类名
System.out.println(c1.getName());
// 包名
System.out.println(c1.getPackage());
// 父类
System.out.println(c1.getSuperclass());
// 接口
System.out.println(c1.getInterfaces());
// 方法 包含父类的方法
System.out.println(c1.getMethods());
// 属性
System.out.println(c1.getFields());
// 构造器
System.out.println(c1.getConstructors());
// 实例化对象
System.out.println(c1.newInstance());
}
}
通过反射对类的私有属性赋值。
public class Test1 {
public static void main(String[] args) throws NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException {
Class c1 = Person.class;
// 私有属性的 Field对象
Field field = c1.getDeclaredField("name");
Person obj = (Person)c1.newInstance();
//给Field属性设置权限
field.setAccessible(true);
// 通过 Field 给 name 赋值
field.set(obj, "张三");
// 取值
System.out.println(field.get(obj));
// 验证跟类关联了
System.out.println(obj.getName());
}
}
通过反射对象调用方法。
public class Test1 {
public Test1() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
Class t1 = Person.class;
// 反射公有方法,返回 Method 对象
Method m1 = t1.getMethod("hello", String.class, int.class);
Object obj = t1.newInstance();
//通过Method 对象 的 invoke 调用类的 hello 方法
m1.invoke(obj, "张三", 18);
}
}
设计模式。一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。可以简单理解为特定问题的固定解决方法。
工厂设计模式。开闭原则,对拓展开放、对修改关闭。
工厂设计模式 和 反射结合,完成动态的对象创建。
//
public class Cat {
public String name;
public Cat() {
// TODO Auto-generated constructor stub
}
}
//
public class Dog {
public String name;
public Dog() {
// TODO Auto-generated constructor stub
}
}
// 工厂类的方法里,将反射对象传入返回实例化对象
public class Factory {
public Factory() {
// TODO Auto-generated constructor stub
}
public static Object newInstance(Class<?> cla) throws InstantiationException, IllegalAccessException {
return cla.newInstance();
}
}
public class Test1 {
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
// 工厂模式 + 反射,一个方法可以实例化多个类
Object o1 = Factory.newInstance(Dog.class);
Dog dog = (Dog)o1;
Object o2 = Factory.newInstance(Cat.class);
Cat cat = (Cat)o2;
dog.name = "小狗狗";
cat.name = "小猫猫";
}
}
单例模式。只允许创建一个该类的对象。
饿汉式。类加载时创建,天生线程安全。
public class Single1 {
// 私有 静态当前类属性
private static final Single1 single = new Single1();
// 私有构造方法
private Single1() {
}
public static Single1 single() {
// sleep 验证多线程安全,实际使用时去掉
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return single;
}
}
懒汉式。使用时创建,线程不安全,加同步。
public class Single2 {
private static Single2 single = null;
private Single2() {
}
public static synchronized Single2 single() {
if (single == null) {
// sleep 验证多线程安全,实际使用时去掉
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
single = new Single2();
}
return single;
}
}
多线程验证单例模式只创建了一个实例对象。
// 线程
public class MyThread extends Thread {
public MyThread() {
}
@Override
public void run() {
Single1 single1 = Single1.single();
System.out.println(single1);
Single2 single2 = Single2.single();
System.out.println("single2 " + single2);
}
}
//
public class Test1 {
public Test1() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) {
// TODO Auto-generated method stub
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
MyThread t3 = new MyThread();
MyThread t4 = new MyThread();
// 打印地址相同
t1.start();
t2.start();
t3.start();
t4.start();
}
}
枚举。
// 定义枚举
public enum MyEnum {
EMAN,EWOMAN,ENOT
}
//
public class Test {
public static void main(String[] args) {
MyEnum enum1 = MyEnum.EWOMAN;
switch (enum1) {
case EMAN:
System.out.println("男神");
break;
case EWOMAN:
System.out.println("女神");
break;
case ENOT:
System.out.println("未知");
break;
default:
break;
}
}
}
注解。注解(Annotation)是代码里的特殊标记, 程序可以读取注解,一般用于替代配置文件。
开发人员可以通过注解告诉类如何运行。
在 Java 技术里注解的典型应用,可以通过反射技术去得到类里面的注解,以决定怎么去运行类。
常见注解。@Override,继承;@Deprecated,标注过时的类和方法。
定义注解使用 @interface 关键字,注解中只能包含属性。
//
//@interface:定义注解类里面都是属性
@Retention(RetentionPolicy.RUNTIME) //定义元注解:注解的注解
@Target(ElementType.METHOD) //通过 Method 类型去执行的
public @interface MyAnnotation {
String name(); //注解类的属性定义
int age() default 33; //int age = 33;
// Class c() default Object.class; //定义Class类型
// MyEnum enum1(); //定义枚举类型
// MyAnnotation annotation(); //定义注解类型
// int[] as(); //一维数组
}
//
public class Person {
@MyAnnotation(name = "zsf",age = 99)
public void show() {
System.out.println("show....");
}
}
//
public class Test {
public static void main(String[] args) throws NoSuchMethodException, SecurityException {
//通过反射及技术,给注解类中的属性赋值,和取值
Class c = Person.class; //得到反射对象
Method method = c.getMethod("show"); //在show方法中给注解了赋值
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class); //传注解类对象,获取注解对象
System.out.println(annotation.name()); //取出注解的值
System.out.println(annotation.age());
}
}