System.out.println(Class.forName("java.lang.String").getClassLoader());
不使用泛型从iterator读取的东西都是Object类型。如果不使用泛型,必须使用instanceof来判断然后强制转型才可以。
package cn.text.hashmap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Text02 {
public static void main(String[] args) {
Collection coll = new ArrayList();
Father father = new Father();
coll.add(father);
Iterator iterator = coll.iterator();
Object next = iterator.next();
//取出来的都是object类型的,没有run()方法,只能加强制转换
if (next instanceof Father) {
Father father1 = (Father)next;
father1.run();
}
}
}
class Father{
void run(){
System.out.println("父亲在跑步");
}
}
使用泛型之后只能在集合中储存限定的数据,而且迭代取出来的也是限定类,不用加强转
package cn.text.hashmap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Text02 {
public static void main(String[] args) {
Collection<Father> coll = new ArrayList<Father>();
Father father = new Father();
coll.add(father);
Iterator<Father> iterator = coll.iterator();
Father next = iterator.next();
//直接取出来的就是Father类,而不是Object类
next.run();
}
}
class Father{
void run(){
System.out.println("父亲在跑步");
}
}
package cn.text.hashmap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Text02 {
public static void main(String[] args) {
// new ArrayList<>()的<>中的限定类可以不写,它会自动推断
Collection<Father> coll = new ArrayList<>();
Father father = new Father();
coll.add(father);
Iterator<Father> iterator = coll.iterator();
Father next = iterator.next();
next.run();
}
}
class Father{
void run(){
System.out.println("父亲在跑步");
}
}
- 当数据流从内存流出到输出
- 当数据流流入内存加流入
- 字节流:按照字节的方式读取数据,一次读取一个字节,等同于读取8个二进制,这种流是万能的,什么都可以读。比如:文本、视频、音频、图片
- z字符流:按照字符来读取数据,一次读取一个字符,只能读取纯文本文件,不能读取视频、音频、图片
- InputStream(输入字节流)
- OutputStream(输出字节流)
- reader(输入字符流)
- writer(输出字符流)
- 必须用.properties结尾
package cn;
import java.util.ResourceBundle;
public class reflectJava {
public static void main(String[] args) {
//不需要流对象,直接用ResourceBundle.getBundle获取properties文件,读取里面的key-value
ResourceBundle resoure = ResourceBundle.getBundle("db");
System.out.println(resoure.getString("username"));
}
}
- 编译器可以检查带注解的成员、属性、类等,让成员、属性、类等做一些限制。
- 可以起到一个flag的作用,配合反射机制完成其他功能。
byte short int long float double boolean char String Class Annontation enum 以及以上的类型数组
这是定义的注解的.java文件
package cn.text.hashmap;
import java.lang.annotation.*;
//这是定义的注解
@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MyAnnontation {
String s1();
boolean flag();
Myenum myEnum(); //定义的枚举属性
MyAnnontation02 myAnnontation02(); //定义的注解属性
Class classtype();
}
@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD})
@interface MyAnnontation02 {
}
enum Myenum{
TEXT01;
}
这是定义的tAnnotationText.java文件
public class AnnotationText {
@MyAnnontation(s1 = "1111",flag = true,myEnum = Myenum.TEXT01, classtype = String.class,myAnnontation02 = @MyAnnontation02)
public static void main(String[] args) {
System.out.println("111111111");
}
}
引导类加载器(爷)
扩展类加载器(爸)
系统类加载器(孙子)
- 先去引导类加载器加载,找到直接返回。
- 引导类加载器找不到再去扩展类加载器加载,找到直接返回。
- 扩展类加载器找不到直接去系统加载器加载。
- 引导类加载器
负责加载rt.jar里面的类加载
//这是引导类加载器,无法直接获取
System.out.println(Class.forName("java.lang.String").getClassLoader());
//输出位null
- 扩展类加载器
加载ext包里面的类
System.out.println(ClassLoader.getSystemClassLoader().getParent());
//输入为sun.misc.Launcher$ExtClassLoader@1b6d3586
- 系统类加载器
加载classpath路径里面的class
System.out.println(ClassLoader.getSystemClassLoader());
//输出为sun.misc.Launcher$AppClassLoader@18b4aac2
反射可以操作整个字节码文件(.class文件),可以读和修改字节码文件。
//这是第一种方法
try {
Class c3 = Class.forName("java.util.ArrayList");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//这是第二种方法
String s = "";
Class c1 = s.getClass();
//这是第三种方法
Class c2 = String.class;
通过反射获取的相同字节码只在jvm加载一份
public class text{
public static void main(String[] args) {
String s1 = "";
Class c1 = s1.getClass();
Class c2 = String.class;
if (c1==c2){
System.out.println("内存地址一样");
}
}
}
- 增加了代码的灵活性、扩展性。
通过加载配置文件中的类名来创建对象,如果需要创建别的对象,只需要改变配置文件的类名就欧克,不要去动代码里面的东西。增加了代码的灵活性。
如果使用new来创建对象,当需要创建别的对象时你需要去改变代码,这样就降低了代码的可扩展性。
package cn;
import java.util.Date;
import java.util.ResourceBundle;
public class ReflectJava {
public static void main(String[] args) {
ResourceBundle resoure = ResourceBundle.getBundle("cn");
String className = resoure.getString("className");
try {
Class c = Class.forName(className);
Date o = (Date)c.newInstance();
System.out.println(o);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}
- 操作类的字段的名字、类型、修饰符
package cn;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class ReflectJava03 {
public static void main(String[] args) {
try {
Class c = Class.forName("cn.User");
//根据该字段可以创建类的对象
Field name = c.getDeclaredField("name");
User user = (User)name.get(c);
System.out.println(c.getName()); //c.getName() 获取类的名字
System.out.println(c.getSimpleName());//获取类的简单名字
System.out.println(c.getField("age"));//获取类对象只有public修饰的字段
System.out.println(c.getFields());//获取类对象只有public修饰的所有字段
System.out.println(c.getDeclaredField("age"));//获取类对象的age字段
Field[] df = c.getDeclaredFields();//获取类对象的所有字段
for (Field f : df){
//获取该申明该字段的类
System.out.println("f.getDeclaringClass().getName()===="+f.getDeclaringClass().getName());
//获取该字段的类型
//如果类型中带泛型修饰,则只会返回类型,不会返回泛型
System.out.println("f.getType()"+f.getType());
//获取该字段的类型
//如果类型中带泛型修饰,该字段的类型和泛型全部返回
System.out.println("f.getGenericType()"+f.getGenericType());
//获取该字段的名字
System.out.println(f.getName());
//f.getModifiers()获取该字段的修饰符,返回的是修饰符的对应数字。
//可以使用Modifier.toString("修饰符代表的数字参数")把数字转换成修饰符
System.out.println(Modifier.toString(f.getModifiers()));
System.out.println("f.getAnnotatedType()"+f.getAnnotatedType());
System.out.println("===========================");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}
class User{
public static boolean sex;
public int age;
private String name;
String addr;
protected int heiht;
}
- 对象的赋值和读取
package cn;
import java.lang.reflect.Field;
public class ReflectJava04 {
public static void main(String[] args) {
try {
Class c = Class.forName("cn.User");
User user = (User)c.newInstance();
Field name = c.getDeclaredField("name");
//设置为true才可以操作对象的私有属性
name.setAccessible(true);
name.set(user,"1111");
System.out.println(name.get(user));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}
class User {
@Text(name = "wangwu")
public static boolean sex;
public static int age = 18;
private static String name = "jiruixin";
String addr;
protected int heiht;
List<Integer> list;
}
- 操作类字段的注解
package cn;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
public class ReflectJava03 {
public static void main(String[] args) {
try {
Class c = Class.forName("cn.User");
Field sex = c.getDeclaredField("sex");
//获取该字段的注解的对象
//获取到该对象就可以查看该对象的信息
Text annotation = sex.getAnnotation(Text.class);
//查看该字段注解的类型,返回的是Class
System.out.println(annotation.annotationType());
//获取该字段的所有注解的对象
Annotation[] annotations = sex.getAnnotations();
//Annotation[] da2 = sex.getDeclaredAnnotations();
//System.out.println("1"+sex.getAnnotatedType());
for (Annotation a:annotations){
Text c1 = (Text) a;
System.out.println("注解数组"+c1.name());
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}
class User {
@Text(name = "wangwu")
public static boolean sex;
public static int age = 18;
private static String name = "jiruixin";
String addr;
protected int heiht;
List<Integer> list;
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.ANNOTATION_TYPE,ElementType.FIELD})
@interface Text{
String name() ;
}
- 获取方法的基本信息
package cn;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectJava04 {
public static void main(String[] args) {
try {
Class c = Class.forName("cn.User");
Method[] methods2 = c.getDeclaredMethods();
for (Method m : methods2){
//拿到方法的所有参数,进行遍历得到每个参数
Class[] p = m.getParameterTypes();
for (Class c1 : p){
System.out.println("p "+c1.getSimpleName());
}
//方法的返回值的Class
System.out.println("1 "+m.getReturnType());
//方法的名字
System.out.println("3 "+m.getName());
System.out.println("------------------");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.List;
class User {
public String login(String username, String admin){
if ("admin".equals(username)&& "123".equals(admin)){
return "登录成功";
}else {
return "登陆失败";
}
}
private static String login4(String username, String admin){
if ("admin".equals(username)&& "123".equals(admin)){
return "登录成功";
}else {
return "登陆失败";
}
}
}
- 调用对象的方法
package cn;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectJava04 {
public static void main(String[] args) {
try {
Class c = Class.forName("cn.User");
User user = (User)c.newInstance();
Method login = c.getDeclaredMethod("login4", String.class, String.class);
//操作私有需要把setAccessible设为true
login.setAccessible(true);
System.out.println(login.invoke(user,"admin","123"));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.List;
class User {
public String login(String username, String admin){
if ("admin".equals(username)&& "123".equals(admin)){
return "登录成功";
}else {
return "登陆失败";
}
}
private static String login4(String username, String admin){
if ("admin".equals(username)&& "123".equals(admin)){
return "登录成功";
}else {
return "登陆失败";
}
}
}
- 调用构造参数创建对象
package cn;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ReflectJava05 {
public static void main(String[] args) {
try {
Class c = Class.forName("cn.User");
//java的函数比较是名字和参数列表,有一个一样就是不一样
//调用什么样的构造函数就看你参数
Constructor dc = c.getConstructor(String.class);
User user = (User)dc.newInstance("jiruixin");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
类型...是可变长度参数,可以用数组给可变长度参数传值
package com.company;
import java.lang.String;
public class Main {
public static void main(String[] args) {
String[] strings = {"s1", "s2", "s3","s4"};
//用数组给User的构造函数传值
User user = new User(strings);
}
}
class User{
//用可变长度参数来接受数组
public User(String... ss){
for(String s : ss){
System.out.println(s);
}
System.out.println(ss);
}
}
这是springboot的启动类
@SpringBootApplication
public class FirstdemoApplication {
public static void main(String[] args) {
SpringApplication.run(FirstdemoApplication.class, args);
}
}
SpringApplication.run进入一下代码
//首先进入这个方法
//Class<?> primarySource = FirstdemoApplication.class
//String... args = args(main方法的参数)
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
//调用下面的run方法
return run(new Class[]{primarySource}, args);
}
//Class<?> primarySource = FirstdemoApplication.class
//String... args = args(main方法的参数)
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
//这是两步,第一步是实例SpringApplication对象,第二步是调用run方法
return (new SpringApplication(primarySources)).run(args);
}
进入SpringApplication对象的构造方法
//首先进入这个方法
//Class<?>... primarySources = FirstdemoApplication.class
public SpringApplication(Class<?>... primarySources) {
//调用下面的构造方法
this((ResourceLoader)null, primarySources);
}
//ResourceLoader resourceLoader = null
//Class<?>... primarySources = FirstdemoApplication.class
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
/****************************初始化一些配置*****************************************/
this.sources = new LinkedHashSet();
this.bannerMode = Mode.CONSOLE;
this.logStartupInfo = true;
this.addCommandLineProperties = true;
this.addConversionService = true;
this.headless = true;
this.registerShutdownHook = true;
this.additionalProfiles = Collections.emptySet();
this.isCustomEnvironment = false;
this.lazyInitialization = false;
this.applicationContextFactory = ApplicationContextFactory.DEFAULT;
this.applicationStartup = ApplicationStartup.DEFAULT;
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
/****************************初始化一些配置*****************************************/
//******************重要**************************************//
//这是把run方法中class的类的数组变成了set列表。
this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
//判断是否是web应用
this.webApplicationType = WebApplicationType.deduceFromClasspath();
this.bootstrappers = new ArrayList(this.getSpringFactoriesInstances(Bootstrapper.class));
//把META-INF文件下的spring.factories里面的ApplicationContextInitializer类实例化并且保存在列表里
//?有什么用
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
//把META-INF文件下的spring.factories里面的ApplicationListener类实例化并且保存在列表里
//?有什么用
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
//去堆栈信息里查找有main方法的类
this.mainApplicationClass = this.deduceMainApplicationClass();
//******************重要**************************************//
//到这里对象的创建全部完成,剩下就是调用该对象的run方法
}
调用SpringApplication.run()方法
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
ConfigurableApplicationContext context = null;
this.configureHeadlessProperty();
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
/*****************************重要**************************************************/
//获取应用的环境
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
//忽略环境里的一些信息
this.configureIgnoreBeanInfo(environment);
//打印图标
Banner printedBanner = this.printBanner(environment);
//创建上下文容器
context = this.createApplicationContext();
//设置应用启动器
//?不理解
context.setApplicationStartup(this.applicationStartup);
/*****************************非常重要********************************************/
//这是注册了主类到容器里
this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
//这里面是注册配置类和实例化
this.refreshContext(context);
/*****************************非常重要********************************************/
this.afterRefresh(context, applicationArguments);
stopWatch.stop();
/*****************************重要**************************************************/
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}
listeners.started(context);
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {
this.handleRunFailure(context, var10, listeners);
throw new IllegalStateException(var10);
}
try {
listeners.running(context);
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
//注册bean的类
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
//初始化tomcat
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//完成实例化
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
- pom.xml增加这个配置文件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
- 在file -> settings -> compiler
- 在shift + ctrl +alt + /(问号按键下面的斜杠)点击registry
- 勾选里面的run,然后重启IDEA
spring:
main:
# 这是让application的延迟对象的实例化,只有用的时候才实例化对象
lazy-initialization: true
devtools:
restart:
# 开启热部署,一般不用配置,默认开启,可以使用这个来关闭
enabled: true
# 只有这个文件里面的东西改变了才会重启
trigger-file: "aa.reloadtrigger"
# 没搞明白
log-condition-evaluation-delta: false