类对象
什么是类对象
类的对象:基于某个类new出来的对象,也称实例对象。
类对象:类加载的产物,封装了一个类的所有信息(类名、父类、接口、属性、方法、构造方法)
获取类对象
通过类的对象,获取类对象
Student s = new Student();
Class c =s.getClasss();
通过类名获取类对象:
Class c = 类名.class;
通过静态方法获取类对象
Class c = Class.forName("包名.类名");
package com.james; /** * 三种方式获取类对象 * @author james * */ public class TestReflection01 { public static void main(String[] args) { Student s = new Student(); // 1. 对象的getClass()方法可以获取类对象 Class<? extends Student> c1 = s.getClass(); System.out.println(c1); // 2. 类.class可以获取类对象 Class<Student> c2 = Student.class; System.out.println(c2); try { // 3. Class.forName(类的全路径字符串); Class<Student> c3 = (Class<Student>) Class.forName("com.james.Student"); System.out.println(c3); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
Student类
package com.james; import java.io.Serializable; import java.rmi.Remote; public class Student implements Serializable, Remote { public static int sid; String name; protected double score; public Student() { } public Student(int sid, String name, double score) { super(); this.sid = sid; this.name = name; this.score = score; } @Override public String toString() { return "Student [sid=" + sid + ", name=" + name + ", score=" + score + "]"; } private void study() { System.out.println("i like java."); } int add(int n1, int n2) { return n1 + n2; } public double minus(double n1, int n2) { return n1 - n2; } }
常用方法
getFields()只能获取该类中的所有的public修饰的属性域
getDeclaredFields()能获取该类中的所有属性域
package com.james; import java.lang.reflect.Field; import java.lang.reflect.Modifier; /** * 三种方式获取类对象 * @author james * */ public class TestReflection02 { public static void main(String[] args) { Student s = new Student(); // 1. 对象的getClass()方法可以获取类对象 Class<? extends Student> c1 = s.getClass(); System.out.println(c1); System.out.println("============="); // 类对象的getFields()只能获取该类中的所有的public修饰的属性域 Field[] fs = c1.getFields(); for (Field f : fs) { System.out.println(f); } System.out.println("============="); // 类对象的getDeclaredFields()能获取该类中的所有属性域 Field[] fs2 = c1.getDeclaredFields(); for (Field f : fs2) { System.out.println(f + "\t" + f.getModifiers() + "\t" + Modifier.toString(f.getModifiers())); } } }
getMethods()方法可以获取自己以及从父类继承过来的所有public修饰的方法
package com.james; import java.lang.reflect.Method; import java.lang.reflect.Modifier; /** * @author james * */ public class TestReflection03 { public static void main(String[] args) { Student s = new Student(); // 1. 对象的getClass()方法可以获取类对象 Class<? extends Student> c1 = s.getClass(); System.out.println(c1); System.out.println("============="); // getMethods()方法可以获取自己以及从父类继承过来的所有public修饰的方法 Method[] ms = c1.getMethods(); for (Method m : ms) { System.out.println(m); } System.out.println("============="); // getDeclaredMethods()方法可以获取自己以及从父类继承过来的所有方法 Method[] ms2 = c1.getDeclaredMethods(); for (Method m : ms2) { System.out.println(m + "\t" + m.getModifiers() + Modifier.toString(m.getModifiers())); } } }
setAccessible(true);设置该方法可以直接被访问
package com.james; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; public class TestReflection04 { public static void main(String[] args) { Student s = new Student(); // 1. 对象的getClass()方法可以获取类对象 Class<? extends Student> c1 = s.getClass(); System.out.println(c1); System.out.println("============="); try { // 获取一个无参的study()方法对象 Method m = c1.getDeclaredMethod("study"); // 设置该方法可以直接被访问 m.setAccessible(true); // 直接调用该方法 m.invoke(s); System.out.println("--------------"); // 获取包含了两个int参数的add()方法对象 Method m2 = c1.getDeclaredMethod("add", int.class, int.class); m2.setAccessible(true); Object obj = m2.invoke(s, 1, 2); System.out.println(obj); } catch (NoSuchMethodException | SecurityException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } }
package com.james; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; public class TestReflection05 { public static void main(String[] args) { //Student s = new Student(); // 1. 对象的getClass()方法可以获取类对象 Class<? extends Student> c1 = Student.class; System.out.println(c1); System.out.println("============="); Constructor<?>[] cs = c1.getConstructors(); for (Constructor<?> c : cs) { System.out.println(c); } } }
设计模式
概念:一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。可以简单理解为特定问题的固定解决方法
好处:使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、重要性
工厂设计模式
开发中有一个非常重要的原则“开闭原则”,对拓展开放、对修改关闭
工厂模式主要负责对象创建的问题
可通过反射进行工厂模式的设计,完成动态的对象创建
单例模式
单例(Singleton):只允许创建一个该类的对象
饿汉式
类加载时创建,天生线程安全
懒汉式
使用时创建,线程不安全,加同步
使用时创建,线程安全
枚举类型
概念:是一个引用类型,枚举是一个规定了取值范围的数据类型
枚举变量不能使用其他的数据,只能使用枚举中常量赋值,提高程序安全性
定义枚举使用enum关键字
枚举的本质:
枚举是一个终止类,并继承Enum抽象类
枚举中常量是当前类型的静态常量
注解
概念:注解(Annotation)是代码里的特殊标记,程序可以读取注解,一般用于替代配置文件
开发人员可以通过注解告诉类如何运行
在Java技术里注解的典型应用是:可以通过反射技术去得到类里面的注解,以决定怎么去运行类。
常见注解:@Override 、@Deprecated
定义注解使用@interface关键字,注解中只能包含属性。
注解属性类型
String类型
基本数据类型
Class类型
枚举类型
注解类型
以上类型的一维数组
元注解
用来描述注解的注解
@Retention:用于指定注解可以保留的域
@Target:指定注解用于修饰类的哪个成员
package com.james; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD}) @Retention(RetentionPolicy.SOURCE) public @interface MyAnnotation { }