JAVA API---反射,注解,JVM

package ReflectDemo;

import java.awt.List;

/*
 *   反射
 *   1.了解
        	数据库
       		集群:一堆完成同一功能的服务器搭建的架构。
       		耦合:两个模块之间相互关联
       		
       		Service处理数据   
       				1.Dao d=new MySQLDao(); d.add()    ->Dao d=new OracleDao() d.add();
       				2.读取sql.properties文件,根据读取到的内容来确定使用哪一个类,如何将读取到的字符串映射成对应的类?-------反射
       		Dao操作数据库的接口,定义所有需要操作数据库的方法。
       				1.MysqlDao ,OracleDao
       			
       	      配置文件:2.sql.properties  dao=MySQLDao();
       	     
      2.反射:在获取这个类的字节码的基础上来解剖这个类。
           
      
         Class,  	代表字节码的类,代表类的类
      //Package,	代表包的类     
         Field,  	代表属性的类
         Method, 	代表方法的类
         Constructor代表构造方法的类
       //Annotation 代表注解的类
         
         
      3.获取Class对象
        3.1通过类名.class的方式来获取指定类的字节码
        3.2通过对象.getClass()来获取对象对应的实际类的字节码
        3.3通过Class.forName(类的全路径名);获取指定类的字节码
 */
public class ReflectDemo01 {
	public static void main(String[] args) throws ClassNotFoundException {
		
		//Class是一个代表类的类,因此每一个Class对象实际上要对应一个类
		
//-------------------3.1通过类名.class的方式来获取指定类的字节码-----------------------		
		
		//A引用类型 1.类  2接口  3.数组
		
		//1.clz代表String类的字节码
		Class<String> clz=String.class;   
		System.out.println(clz);            //输出class java.lang.String
		
		
		//2.clz2代表list接口的字节码
		Class<List>  clz2=List.class;
		System.out.println(clz2);          //输出class java.awt.List
		
		//3.clz3代表int[] 数组的字节码
		Class<int[]> clz3= int[].class;
		System.out.println(clz3);         //输出class [I
		  
		
		//B基本类型
		//double的字节码
		Class clz4=Double.class;   
		System.out.println(clz4);         //输出class java.lang.Double
		
//------------------3.2通过对象.getClass()来获取对象对应的实际类的字节码 ---------------------------------		
		//clz5代表String类的字节码
		Object o="abc";
		Class<Object>  clz5=(Class<Object>)o.getClass();
		System.out.println(clz5);         //输出class java.lang.String
		
//--------------------3.3通过Class.forName(类的全路径名);获取指定类的字节码 -------------------------------------
		Class<String> clz6=(Class<String>) Class.forName("java.lang.String");
		System.out.println(clz6);         //输出class java.lang.String
	}
}
package ReflectDemo;

import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectDemo02 {
	public static void main(String[] args) throws  Exception{
	
//             (将读取到的字符串映射成对应的类)
		
//------------------无参产生对象.newInstance()-------------------	
		//1.获取到了Object类的字节码    
		Class<Object> clz=(Class<Object>) Class.forName("java.lang.Object");
		//产生Object对象   .newInstance()
		Object o=clz.newInstance();
		System.out.println(o);           //输出java.lang.Object@55f96302
		
		
		//2.获取String对象
		Class<String> clz2=(Class<String>) Class.forName("java.lang.String");
		//要求这个类必须提供无参构造   .newInstance()
		String str=clz2.newInstance();
		System.out.println(str);         //输出空
		 
		
//------------------4.有参产生对象  Constructor代表构造方法的类-------------------------------	
//1.获取public构造方法
//.getConstructor(参数类)获取public构造方法
//.newInstance(参数)    执行构造方法
		

//2.获取私有构造方法
//.getDeclaredConstructor(参数类)
//.setAccessible(true); 暴力破解
//.newInstance(参数)    执行构造方法
	
//3.获取所有构造方法
//.getDeclaredConstructors()
		
		
		//3.获取有参构造的Integer对象
		Class<Integer> clz3=Integer.class;
		//Integer in=clz3.newInstance();  错误不允许用.newInstance()无参构造
		
		//获取类中的构造方法,参数类型为Integer(int)
		Constructor<Integer> c=clz3.getConstructor(int.class);
		//执行构造方法,创建对象类的对象
		Integer in=c.newInstance(5);
		
		/*
		 * Constructor<Integer> c=clz3.getConstructor(int.class);
		   Integer in=c.newInstance(5);
		   等价于
		   Integer in=new Integer(5);
		 */
		
		System.out.println(in);         //输出5
		
		
		//4.1获取有参构造的String对象
		Class<String> clz4=String.class;
		Constructor<String> c2=clz4.getConstructor(String.class);
		//执行构造方法,创建对象类的对象
		String str2=c2.newInstance("abc");
		System.out.println(str2);     //输出abc
		
		
		//4.2.getConstructor()只能获取public的构造方法
		//Constructor<String> c3=clz4.getConstructor(char[].class,boolean.class);    出错
		//System.out.println(c3);
		
		//4.3.getDeclaredConstructor()获取这个类的任意的构造方法,不区分权限修饰符
		Constructor<String> c4=clz4.getDeclaredConstructor(char[].class, boolean.class);
		//.setAccessible(true)暴力破解/拆除,会打破封装特性
		c4.setAccessible(true);
		System.out.println(c4.newInstance(new char[] {'a','d','s'} ,true));   //输出ads

		
		
		//5.获取所有的构造方法
		Class<String> clz5=String.class;
		Constructor[]  cs=clz5.getDeclaredConstructors();
		for(Constructor cst:cs) {
			System.out.println(cst);
		}
		//输出
		/*
		 * public java.lang.String(byte[],int,int)
			public java.lang.String(byte[],java.nio.charset.Charset)
			public java.lang.String(byte[],java.lang.String) throws java.io.UnsupportedEncodingException
			public java.lang.String(byte[],int,int,java.nio.charset.Charset)
			public java.lang.String(byte[],int,int,java.lang.String) throws java.io.UnsupportedEncodingException
			java.lang.String(char[],boolean)
			public java.lang.String(java.lang.StringBuilder)
			public java.lang.String(java.lang.StringBuffer)
			public java.lang.String(byte[])
			public java.lang.String(int[],int,int)
			public java.lang.String()
			public java.lang.String(char[])
			public java.lang.String(java.lang.String)
			public java.lang.String(char[],int,int)
			public java.lang.String(byte[],int)
			public java.lang.String(byte[],int,int,int)
		 */
		
//----------------------5.获取类中方法Method代表方法的类--------------	
//----------Method .getDeclaredMethod()----------
//----------[setAccessible(true)暴力破解私有]---
//----------invoke()执行----------
		
		//6.1获取类中指定的方法 public  charAt(int)
		Method m=clz5.getDeclaredMethod("charAt", int.class);
		String str4="sadadsa";
		//执行方法
		 char c5=(char) m.invoke(str4, 5);
		 System.out.println(c5);    //输出s
		 
		 //获取字符串的长度
		 Method m1=clz5.getDeclaredMethod("length");
		 int  len=(int) m1.invoke(str4);
		 System.out.println(len);    //输出7
		 
		 //6.2获取类中所有的方法  包含私有
		Method m2=clz5.getDeclaredMethod("indexOfSupplementary",int.class,int.class);     
	    //暴力破解/拆除,会打破封装特性
		 m2.setAccessible(true);
		 int i=(int) m2.invoke(str4, 1,5);
		 System.out.println(i);    //输出-1


//------------------6.获取类中的属性Field-代表属性的类--------------------
//-------------Field .getDeclaredField(属性)--------------------------------
//-------------[setAccessible(true)暴力破解私有]-------------------------
//--------------set设置属性,get获取属性--------------------------------
		 Class<String> clz6=String.class;
		 Field f=clz6.getDeclaredField("hash");
		 System.out.println(f);            //输出private int java.lang.String.hash
		 f.setAccessible(true);
		 f.set(str, 248);               //设置属性
		 System.out.println(f.get(str));//获取属性   //输出248
		 

//----------------7. getEnumConstants()获取枚举常量------------------------------------
		 //获取枚举中所有的枚举常量
		 Class<Level> clz7=Level.class;
		 Level[] is=clz7.getEnumConstants(); //如果这个类不是枚举,返回null
		 for(Level lv:is) {
			 System.out.println(lv);   //输出ABCD
		 }
		// 如果这个类不是枚举,则返回null
		System.out.println(clz.getEnumConstants());//输出null
		 
		
//--------------8. 获取所在的包 Package .getPackage()---------------------
		Package p = clz7.getPackage(); 
		System.out.println(p);         //输出package ReflectDemo
		
		
		
//---------------9. 获取类的全路径名  getName()------------------------------
		 System.out.println(clz7.getName()); //输出ReflectDemo.Level
		
		 
		 
//--------------10. 只获取类名   .getSimpleName()-----------------------------
		System.out.println(clz7.getSimpleName());//输出Level

			// 如果这个类不是枚举,则返回null
			// System.out.println(clz.getEnumConstants());
		 
		 
		 
	
// --------------11.获取这个类实现的接口  .getInterfaces()-------------------------
		// Class<String> clz6=String.class;
		 Class[] cs2=clz6.getInterfaces();
		 for(Class sd:cs2) {
			 System.out.println(sd);  //输出interface java.io.Serializable interface java.lang.Comparable interface java.lang.CharSequence
		 }

//--------------12.获取这个类的父类        .getSuperclass()-------------------------
		 System.out.println(clz6.getSuperclass()); //输出class java.lang.Object
		 

		
	
//-----------13.判断是否是匿名内部类   isAnonymousClass()-----------------------
		 A a=new A() {
			 
		 };
		 System.out.println(a.getClass().isAnonymousClass());  //输出true

//-----------14.判断是否是方法内部类  isLocalClass()------------------------------
		 class B{ }
		 System.out.println(B.class.isLocalClass());    //输出true
		 
//-----------15.判断是否是成员内部类  .isMemberClass()----------------------------
		 System.out.println(B.class.isMemberClass());    //输出false
		System.out.println(String.class.isMemberClass()); //输出false
		 

//------------16. 判断是否是一个基本类型  .isPrimitive()--------------------
		Class<Object> clz10 = Object.class;
		
		System.out.println(clz.isPrimitive());        //输出false
		System.out.println(short.class.isPrimitive());//输出true
		
		
//------------17. 判断参数是否继承了当前的类 .isAssignableFrom()------------------
		System.out.println(Serializable.class.isAssignableFrom(String.class)); //输出true
		 
		Class<Object> clz9=Object.class;
		 System.out.println(clz9.isAssignableFrom(Object.class));   //输出true
		
	
//----------- 18.判断是否是数组     .isArray()-----------------------------
		 Class<String[]> clz8=String[].class;
		 System.out.println(clz8.isArray());              //输入true
		 
		 
//------------19.判断是否是接口     .isInterface()---------------------------
		 System.out.println(clz8.isInterface());    //输出false
		 
		 
//------------20.判断对象是否是指定类型的实例 .isInstance()---------------------
		 Object z="abc";
		 System.out.println(clz8.isInstance(z));    //输出false
		 
		
		
		 
		
	}
}

enum Level{
	A,B,C,D;
}

class A{
	
}
package ReflectDemo;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectDemo03 {
	public static void main(String[] args) throws Exception {
		Class<String> clz=String.class;
		
//------------1.获取属性的声明类型 .getType()-----------------
		Field f=clz.getDeclaredField("hash");
		System.out.println(f.getType());       //输出int
		
		
//-----------2.判断是的是一个枚举常量.isEnumConstant()------------------
		System.out.println(f.isEnumConstant());//输出false
		
		
//----------3.获取这个方法抛出的异常.getExceptionTypes()--------------
		Method m=clz.getDeclaredMethod("getBytes", String.class);
		
		Class[] es=m.getExceptionTypes();
		for(Class e:es) {
			System.out.println(e);  //输出class java.io.UnsupportedEncodingException
		}
		
		
//-------------4.获取方法名 .getName()---------------------------------------
		System.out.println(m.getName());  //输出getBytes
		
//-----------5.获取方法参数的类型 .getParameterTypes()---------------------
		Class[] ps=m.getParameterTypes();
		for(Class e:ps) {
			System.out.println(e);      //输出class java.lang.String
		}
		
//------------6.获取返回值类型  .getReturnType()-----------------------
		System.out.println(m.getReturnType()); //输出class [B
		
//-------------7.判断是否有可变参数 .isVarArgs()----------------------
		System.out.println(m.isVarArgs());  //输出false
		
		
		//数据库的没写完 看一下------------------
	}
}
package Note;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/*
 * 注解:
 *   给程序看的解释,在JAVA中注解的父类是Annotation
 *  1.
 *    1.1用@interface定义一个注解
 *    1.2如果在注解中直接定义一个属性,那么这个属性默认是一个静态常量public static final
 *    1.3注解中的属性 加() 注解中的属性只能是基本类型,枚举,String,Class,其他注解类型,以及它们定义的一维数组
 *    1.4default指定默认值
 *    1.5.如果注解中的属性是一维数组,并且在赋值的时候,一维数组中只有一个值,可以直接将这个值赋值给属性    一维数组多个值赋值 { , } 	
 *    1.6如果注解中只有一个属性并且名字是Value,那么在使用这个注解的时候可以省略属性不写
 * 
 *  2.元注解:修饰注解的注解
 *    2.1@Target限定注解的使用范围
 *    2.2@Retention 限制注解的生命周期   --------听一下--------------234--
 *    2.3@Documented 限定这个注解在使用的时候产生到文档中
 *    2.4@Inherited  限制此注释可以作用在子类上  
 *    
 *  
 */


//1.5如果注解中的属性是一维数组,并且在赋值的时候,一维数组中只有一个值,可以直接将这个值赋值给属性    一维数组多个值赋值 { , } 							           
@Time(year=2018,month=07,time= {2,5})

//1.6如果注解中只有一个属性并且名字是Value,那么在使用这个注解的时候可以省略属性不写
@SAnno("ded")

public class NoteDemo {
	@SAnno("ded")
	public void m1(@SAnno("ded") int i) {};
}

//1.1用@interface定义一个注解
@interface Time{
	//1.2如果在注解中直接定义一个属性,那么这个属性默认是一个静态常量
	//public static final int year=18
	//int year=18 ;
	
	
	//1.3注解中的属性 加()
	//注解中的属性只能是基本类型,枚举,String,Class,其他注解类型,以及它们定义的一维数组
	int year();
	int[] month();
	double[] time();
	int day()default 28;   //1.4.default指定默认值
	
	
	//boolean flag();   对
	//Object  o();  1.3出错,注解中的属性只能是基本类型,枚举,String,Class,其他注解类型,以及它们定义的一维数组
	//String str();
}

//2.1@Target 限定注解的使用范围
//注解在类,属性,方法,参数上使用
@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD, ElementType.PARAMETER})


//2.3@Documented 限定这个注解在使用的时候产生到文档中
@Documented  
@interface SAnno{
	String value();//1.6如果注解中只有一个属性并且名字是Value,那么在使用这个注解的时候可以省略属性不写
}

package JVM;
/*
 * JVM参数
 * 
 标准参数:-d,-ea
 非标准参数: -X
 扩展参数:-XX
 
 1.栈内存
 每一个线程都有一个独立的栈内存,因此栈内存的大小影响线程的个数
 JVM限定了栈内存的大小不能超过2G或者物理内存的1/3(取两者的较小值)
 * 例电脑内存4G 最多1/3=1.3G      电脑内存16G最多2G
 * 
 *-Xss128K 表示限定栈内存的大小为128K ,右键Run as -> Run configurations->Arguments->VM arguments-> 输入-Xss128K
 *
 *2.堆内存
 *-Xmn 表示限定新生代的大小
 *-Xms 表示限定堆内存的初始大小
 *-Xmx 表示限定堆内存的最大值
 *-XX:+PrintGCDetails 打印GC运行细节
 *-Xmn5M -Xms10M -Xmx10M -XX:+PrintGCDetails 
 *
 *注意:对象在创建之后先试图放入新生代,如果新生代存不开,则试图放入老生代。
 *
 *
 *
 *
 *
 *3.常见的回收方式
 *Copying 赋值
 *Mark-sweeping标记整理法   //最好,另外两种方法的总和
 *Mark-cleaning标记清理法
 *
 */
public class JVMDemo01 {
   static int count=0;
	public static void main(String[] args) {
		
		//限定栈内存,右键Run as -> Run configurations->Arguments->VM arguments-> 输入-Xss128K       
		//add(10000);       
		//输出到893,会出现893 java.lang.StackOverflowError栈溢出
		
		//右键Run as -> Run configurations->Arguments->VM arguments-> 输入-Xmn5M -Xms10M -Xmx10M -XX:+PrintGCDetails听一下
		byte[] bs=new byte[1024*1024*8];  //8M=8*1024k=8*1024*1024b  
		//出现java.lang.OutOfMemoryError: Java heap space 堆内存溢出
		
		
	}
	
	//递归求和
    public static int add(int n) {
    	System.out.println(count++);
    	if(n==1)return 1;
    	return n+add(--n);
    }
}

 

下面是反射简单例子。

1.Dao接口

package ReflectDemoExer;

/*
 * Dao操作数据库的接口,定义所有需要操作数据库的方法。
       			1.MysqlDao ,OracleDao
 */
//DAO操作数据库的基本接口
public interface Dao {

	void add(String name);

	void delete(String name);

}

2.MySqlDao

package ReflectDemoExer;


//Mysql数据库 继承Dao接口
public class MySQLDao implements Dao {

	@Override
	public void add(String name) {
		System.out.println("向MySQL数据库中添加了用户:" + name);
	}

	@Override
	public void delete(String name) {
		System.out.println("从MySQL数据库中删除了用户:" + name);
	}

}

3.OracleDAO

package ReflectDemoExer;


//OracleDao数据库 继承Dao接口
public class OracleDao implements Dao {

	@Override
	public void add(String name) {
		System.out.println("向Oracle数据库中添加了用户:" + name);
	}

	@Override
	public void delete(String name) {
		System.out.println("从Oracle数据库中删除了用户:" + name);
	}

}

4.dao.properties

dao=ReflectDemoExer.MySQLDao

5.DaoFactory

package ReflectDemoExer;

import java.io.FileInputStream;
import java.util.Properties;


//产生Dao对象,不属于Service业务
public class DaoFactory {
	//单例模式
	private static DaoFactory factory = new DaoFactory();
	private Properties prop;

	//构造私有化
	private DaoFactory() {
	}

	//对外获取Dao对象
	public static DaoFactory getFactory() {
		return factory;
	}

	//来获取真正的Dao对象
	@SuppressWarnings("unchecked")
	public Dao getInstance() {
        //读取properties配置文件
		prop = new Properties();
		try {
			prop.load(new FileInputStream("dao.properties"));

			String dao = prop.getProperty("dao");

			/*
			 *     通过Class.forName(类的全路径名);获取指定类的字节码
					Class<String> clz6=(Class<String>) Class.forName("java.lang.String");
					System.out.println(clz6);         //输出class java.lang.String
			 */
			
			Class<Dao> clz = (Class<Dao>) Class.forName(dao);//把字符串对应成类->反射

			
			/*
			 * 
			 * 无参产生对象.newInstance()
			 * 1.获取到了Object类的字节码    
					Class<Object> clz=(Class<Object>) Class.forName("java.lang.Object");
			  2.产生Object对象   .newInstance()
					Object o=clz.newInstance();
					System.out.println(o);           //输出java.lang.Object@55f96302
			 */
			return clz.newInstance();   //返回实际的Dao对象
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;   //失败返回null
	}

}

6.Service.java

package ReflectDemoExer;

import org.junit.Test;

/*
 * Service处理数据   
       			1.Dao d=new MySQLDao(); d.add()    ->Dao d=new OracleDao() d.add();
       			2.读取sql.properties文件,根据读取到的内容来确定使用哪一个类,如何将读取到的字符串映射成对应的类?-------反射
 */

public class Service {

	Dao d = DaoFactory.getFactory().getInstance();
	//Dao d= new MysqlDao();  d.add(name)
	//Dao d=new OracleDao();  d.add(name)

	public void add(String name) {
		
		// 处理逻辑

		// 处理完成之后需要将数据添加到数据库中
		d.add(name);
	}

	public void delete(String name) {

		d.delete(name);
	}
	
	
	//测试,dao.properties配置文件里dao=ReflectDemoExer.OracleDao输出从Oracle数据库中删除了用户:Tom
	//dao.properties配置文件里dao=ReflectDemoExer.MySQLDao输出从Mysql数据库中删除了用户:Tom   
	@Test
	public void test(){
		
		delete("Tom");
		
	}

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值