概要
注解和注释
注释:给人看
注解:给人看,“解”:加给程序看
Java.Annotation
1、内置注解
//java.lang
//重写
@Override
//废弃
@Deprecated
//抑制编译时警告信息
@SuppressWarnings
2、元注解
元注解:解释其他注解的注解
@Target
用来描述注解的使用范围
@Retention
表示需要在什么级别保存注释信息,用于描述注释的生命周期
(SOURCE[源代码的时候]《CLASS[.class的时候有用]<RUNTIME[运行时有用])
@Document
说明该注解将被包含在javadoc中
@Inherited
说明子类可以继承父类中的该注解
3、自定义注解
//自动继承java.lang.annotation.Annotation接口
public @interface 注解名{
//方法其实是注解的一个参数
(返回值类型是String,Class,enum)method()
}
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2{
//参数
String name() default "";
int age() default 0;
//默认值为-1,代表找不到
int id() default -1;
String[] schools();
}
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation3{
//使用注解的时候可以不用加参数名
String value();
}
4、反射
reflect可以直接改变内部对象
创建对象:new 、clone 、反射[运行时创建对象]
使用反射机制,使得静态的Java变成准动态语言
加载完类之后,在堆内存的方法区产生了一个Class对象(一个类对应一个Class对象)
java.lang.Class
java.lang.reflect
Class类是描述类的类
Class对象只能由系统创建
一个加载类在JVM中只有一个Class实例
一个Class对象对应一个加载到JVM的一个.class文件
获取Class类的实例
a) Person.class;
b) person.getClass();
c) Class.forName(“demo01.Student”);
Person student = new Student();
System.out.println("this person:"+student.name);
Class c1 = student.getClass();
System.out.println(c1.hashCode());
Class c2 = Class.forName("com.kuang.reflection.Student");
System.out.println(c2.hashCode());
Class c3 = Student.class;
System.out.println(c3.hashCode());
Class type = Integer.TYPE;
System.out.println(type);
Class c5 = c1.getSuperclass();
System.out.println(c5);
5、不同类型的Class
Class<Object> c1 = Object.class;
Class<Comparable> c2 = Comparable.class;
Class<String[]> c3 = String[].class;
Class<String[][]> c4 = String[][].class;
Class<Override> c5 = Override.class;
Class<ElementType> c6 = ElementType.class;
Class<Integer> c7 = Integer.class;
Class<Void> c8 = void.class;
Class<Class> c9 = Class.class;
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
System.out.println(c4);
System.out.println(c5);
System.out.println(c6);
System.out.println(c7);
System.out.println(c8);
System.out.println(c9);
//元素类型和维度一样的是同一个类型
int[] a =new int[10];
int[] b =new int[100];
System.out.println(a.getClass().hashCode());
System.out.println(b.getClass().hashCode());
//output
class java.lang.Object
interface java.lang.Comparable
class [Ljava.lang.String;
class [[Ljava.lang.String;
interface java.lang.Override
class java.lang.annotation.ElementType
class java.lang.Integer
void
class java.lang.Class
356573597
356573597
6、内存分析
Java内存分为堆、栈、方法区(特殊的堆)
堆:存放new的对象和数组;可以被所有线程所共享,不会存放别的对象引用
栈:存放基本类型变量(包含这个基本类型的具体数值);引用对象的变量(会存放这个引用在堆里面的具体地址)
方法区:可以被所有线程共享;包含所有class和static变量
类加载过程
程序主动使用某个类时,三步骤:
类的加载->类的链接->类的初始化
-
1.类的加载:将.class文件读入内存方法区,随后在堆中创建一个java.lang.Class对象
-
2.类的链接:将类的二进制代码合并到JVM运行状态之中的过程
– 验证:
– 准备:为类变量(static)分配内存并设置类变量默认初始值的阶段,这些内存都在方法区中进行分配
– 解析:虚拟机常量池中符号引用(常量名)替换成直接引用(地址)的过程 -
3.类的初始化:执行构造器方法是由编译期自动收集所有类变量的赋值动作和静态代码块中的语句合并产生。(类构造器是构造类信息的,不是构造该对象构造器)
package com.kuang.reflection;
public class test05 {
static {
System.out.println("main加载");
}
public static void main(String[] args) {
A a = new A();
System.out.println(A.m);
System.out.println(B.n);
B b= new B();
}
}
class A{
static int m = 100;
static void find(){
System.out.println("find");
}
static{
System.out.println("Astatic代码块");
m=300;
}
public A() {
this.m= 10;
System.out.println("A类无参构造方法");
}
}
class B{
static int n = 150;
static void find(){
System.out.println("find");
}
static{
System.out.println("Bstatic代码块");
n=350;
}
public B() {
System.out.println("B类无参构造方法");
}
}
//output
main加载
Astatic代码块
A类无参构造方法
10
Bstatic代码块
350
B类无参构造方法
类会初始化:
package com.kuang.reflection;
public class test06 {
static {
System.out.println("main加载");
}
public static void main(String[] args) throws ClassNotFoundException {
Son son = new Son();
Class<?> c1 = Class.forName("com.kuang.reflection.Son");
Father father = new Father();
}
}
class Father{
static int b = 2;
static {
System.out.println("father");
}
public Father() {
System.out.println("father constrance");
}
}
class Son extends Father{
static {
System.out.println("son");
m=300;
}
static int m=100;
static final int M =1;
public Son() {
System.out.println("son constrance");
}
}
//output
main加载
father
son
father constrance
son constrance
father constrance
类不会被初始化,类的被动引用
package com.kuang.reflection;
public class test06 {
static {
System.out.println("main加载");
}
public static void main(String[] args) throws ClassNotFoundException {
System.out.println(Son.b);
Son[] array = new Son[5];
System.out.println(Son.M);
}
}
class Father{
static int b = 2;
static {
System.out.println("father");
}
public Father() {
System.out.println("father constrance");
}
}
class Son extends Father{
static {
System.out.println("son");
m=300;
}
static int m=100;
//常量池中的变量
static final int M =1;
public Son() {
System.out.println("son constrance");
}
}
7、类加载器的作用
package com.kuang.reflection;
public class test07 {
public static void main(String[] args) throws ClassNotFoundException {
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);
ClassLoader parent = systemClassLoader.getParent();
System.out.println(parent);
ClassLoader parent1 = parent.getParent();
System.out.println(parent1);
ClassLoader classLoader = Class.forName("com.kuang.reflection.test07").getClassLoader();
System.out.println(classLoader);
ClassLoader classLoader1 = Class.forName("java.lang.Object").getClassLoader();
System.out.println(classLoader1);
System.out.println(System.getProperty("java.class.path"));
//双亲委派机制
//找包的时候找最上层的,如果找不到再往下找
}
}
8、反射常用方法
package com.kuang.reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class test08 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
Class<?> c1 = Class.forName("com.kuang.reflection.User");
System.out.println(c1.getName());
System.out.println(c1.getSimpleName());
System.out.println("============");
//get public field
Field[] fields = c1.getFields();
for (Field field : fields){
System.out.println(field);
}
//get private field
fields = c1.getDeclaredFields();
for (Field field : fields){
System.out.println(field);
}
Field name = c1.getDeclaredField("name");
System.out.println(name);
System.out.println("=========================");
//get father && son public method
Method[] methods = c1.getMethods();
for (Method method:methods){
System.out.println("public:"+method);
}
//only get son all method
methods = c1.getDeclaredMethods();
for (Method method:methods){
System.out.println("private:"+method);
}
Method getNaem = c1.getMethod("getNaem", null);
System.out.println(getNaem);
Method setNaem = c1.getMethod("setNaem", String.class);
System.out.println(setNaem);
System.out.println("============================");
//get public constructor
Constructor[] constructors = c1.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
//get private constructor
constructors = c1.getDeclaredConstructors();
for (Constructor constructor : constructors) {
System.out.println("$"+constructor);
}
Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
System.out.println(constructor);
}
}
实际对象使用
package com.kuang.reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class test09 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
Class c1 = Class.forName("com.kuang.reflection.User");
//类必须是一个无参构造器,构造器需要足够的访问权限
// User user = (User) c1.newInstance();
// System.out.println(user);
//通过构造器来创建参数
// Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
// User user2 = (User)constructor.newInstance("zcc", 001, 18);
// System.out.println(user2);
//通过反射调用普通方法,因为传递参数是写死在程序中的,所以通过反射,可以重新传递参数
User user3 = (User) c1.newInstance();
Method setNaem = c1.getDeclaredMethod("setNaem", String.class);
setNaem.invoke(user3, "zcc");
System.out.println(user3.getNaem());
//通过反射设置操作属性
User user4 = (User) c1.newInstance();
Field name = c1.getDeclaredField("name");
//取消安全检测,访问private属性
name.setAccessible(true);
name.set(user4,"mistyzcc");
System.out.println(user4.getNaem());
}
}
//反射获取方法和普通获取方法效率问题
package com.kuang.reflection;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class test10 {
public static void test1(){
User user = new User();
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100000000; i++) {
user.getNaem();
}
long endTime = System.currentTimeMillis();
System.out.println("1:"+(startTime-endTime));
}
public static void test2() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
User user = new User();
Class c1 = user.getClass();
Method getNaem = c1.getDeclaredMethod("getNaem", null);
getNaem.invoke(user,null);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100000000; i++) {
getNaem.invoke(user,null);
}
long endTime = System.currentTimeMillis();
System.out.println("1:"+(startTime-endTime));
}
public static void test3() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
User user = new User();
Class c1 = user.getClass();
Method getNaem = c1.getDeclaredMethod("getNaem", null);
getNaem.invoke(user,null);
getNaem.setAccessible(true);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100000000; i++) {
getNaem.invoke(user,null);
}
long endTime = System.currentTimeMillis();
System.out.println("1:"+(startTime-endTime));
}
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
test1();
test2();
test3();
}
}
9、反射操作泛型
java采用泛型擦出机制,仅仅给javac编译器使用,确保数据安全性和免去强制类型转换问题,编译完成后,泛型擦除
package com.kuang.reflection;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
public class test11 {
public void test01(Map<String,User> map , List<User> list){
System.out.println("test01");
}
public Map<String,User> test02(){
System.out.println("test02");
return null;
}
public static void main(String[] args) throws NoSuchMethodException {
Method method = test11.class.getMethod("test01", Map.class, List.class);
Type[] genericParameterTypes = method.getGenericParameterTypes();
for (Type genericParameterType : genericParameterTypes) {
System.out.println("#"+genericParameterType);
if (genericParameterType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
}
}
//output
#java.util.Map<java.lang.String, com.kuang.reflection.User>
class java.lang.String
class com.kuang.reflection.User
#java.util.List<com.kuang.reflection.User>
class com.kuang.reflection.User
10、反射获取注解
ORM:Object Relationship Mapping
类和表结构对应
属性和字段对应
对象和记录对应