1. 自动封箱、自动拆箱
2. 泛型
3. 增强for循环
4. 静态导入
5. 可变参数
6. 枚举
7. 注解
8. 反射
9. 动态代理
10. 内省
Integer i=5;//基本类型自动成为包装类
if(i==5){...}//包装类自动成为基本类型
1. 类中的泛型
class Test{
public List getPersons(){
...
}
}
2. 方法中的泛型
public R getResource(R r){
...
}
3. 泛型的上下限
1. 上限
extends 类名或接口名>
2. 下限
super 类名或接口名>
class Demo{
T t;
private void set(T t){
this.t=t;
}
}
class Demo{
T t;
private void set(T t,E e){
this.t=t;
this.e=e;
}
}
函数中的泛型
publiv T method1(E e){
return (T)e;
}
泛型不兼容子类:泛型传入子类出错
泛型的继承:通配符?
无论类还是接口都用extends关键字;限定了泛型的上限(不能直接添加元素--上造型对象反向--doubl和Integet时错误)
public void print(List extends Number> list){
}
super关键字限定下限(能直接添加元素--上造型对象正向,任何父类都可以添加子类对象)
public void print(List super String> list){
}
上下限不能同时出现!!
1. 形式:for(类型 变量名:数组或集合){//具体操作}
2. 举例:
int[] arr={1,2,3};
for(int i : arr){
System.out.print(i+"\t");
}
1. 形式:import static 包名.具体方法名;
2. 举例:
import static java.util.Arrays.sort;
import static java.util.Arrays.toString;
public class Test{
public static void main(String[] args){
int[] arr={1,4,3,2};
arr=sort(arr);
System.out.println(toString(arr));
}
}
1. 形式:类型... 变量名
2. 位置:参数列表的最后一个(类型1 参数名1,类型2 参数名2,类型3... 变量名3)
3. 特性:本质是一个数组;不限定参数个数(0-n);也可以传入数组;
4. 举例:
public int sum(int... arr){
int num=0;
for(int temp:arr){
num+=temp;
}
return num;
}
1. 适用场景:可以固定并能一一列举的场景
2. 形式
enum Season{
Spring,Summer,Autumn,Winter;
}
等价为:
public static final Season Spring = new Season();
public static final Season Sunmmer = new Season();
public static final Season Autumn = new Season();
public static final Season Winter = new Season();
3. 本质为类
4. 枚举定义的枚举常量位置:枚举类的首行
5. 其他性质--允许类的操作
1. 允许定义一切方法和属性
2. 构造函数--只能是私有的
enum Season{
Spring(1),Summer(4),Autumn(7),Winter(11);//必须首行
int num=-1;
public Season(int num){
this.num=num;
}
}
3. 可以写抽象方法
enum Season{
Spring(1){
public void getTime(){
System.out.println("3,4,5");
}
},Summer(4){
public void getTime(){
System.out.println("6,7,8");
}
},Autumn(7){
public void getTime(){
System.out.println("9,10 ,11");
}
},Winter(11){
public void getTime(){
System.out.println("12,1,2");
}
};//必须首行
int num=-1;
public Season(int num){
this.num=num;
}
//抽象方法
public abstract void getTime();
}
4. enum的顶级父类:java.lang.Enum
5. switch(参数)-case结构:参数可为byte/short/char/int,JDK1.5开始支持enum,JDK1.7开始支持String
系统内置标准注解
@Override:用于修饰此方法覆盖了父类的方法;
public class Fruit {
public void displayName(){
System.out.println("水果的名字是:*****");
}
}
class Orange extends Fruit {
@Override
public void displayName(){
System.out.println("水果的名字是:桔子");
}
}
@Deprecated:用于修饰已经过时的方法;
class AppleService {
public void displayName(){
System.out.println("水果的名字是:苹果");
}
/**
* @deprecated 该方法已经过期,不推荐使用
*/
@Deprecated
public void showTaste(){
System.out.println("水果的苹果的口感是:脆甜");
}
public void showTaste(int typeId){
if(typeId==1){
System.out.println("水果的苹果的口感是:酸涩");
}
else if(typeId==2){
System.out.println("水果的苹果的口感是:绵甜");
}
else{
System.out.println("水果的苹果的口感是:脆甜");
}
}
}
@SuppressWarnnings:用于通知java编译器禁止特定的编译警告。
public class FruitService {
@SuppressWarnings(value={ "rawtypes", "unchecked" })
public static List getFruitList(){
List fruitList=new ArrayList();
return fruitList;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public static List getFruit(){
List fruitList=new ArrayList();
return fruitList;
}
@SuppressWarnings("unused")
public static void main(String[] args){
List strList=new ArrayList();
}
}
自定义注解
元注解
1.@Target
@Target(ElementType.TYPE)
public @interface Table {
/**
* 数据表名称注解,默认值为类名称
* @return
*/
public String tableName() default "className";
}
@Target(ElementType.FIELD)
public @interface NoDBColumn {
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
public String name() default "fieldName";
public String setFuncName() default "setField";
public String getFuncName() default "getField";
public boolean defaultDBValue() default false;
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Column {
public String name() default "fieldName";
public String setFuncName() default "setField";
public String getFuncName() default "getField";
public boolean defaultDBValue() default false;
}
/**
*
* @author peida
*
*/
@Inherited
public @interface Greeting {
public enum FontColor{ BULE,RED,GREEN};
String name();
FontColor fontColor() default FontColor.GREEN;
}
自定义
byte,short,char,int,long,float,double,boolean
八种基本数据类型和 String,Enum,Class,annotations等数据类型,
以及这一些类型的数组.例如,String value();这里的参数成员就为String;
简单的自定义注解和使用注解实例:
package annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 水果名称注解
* @author peida
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitName {
String value() default "";
}
package annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 水果颜色注解
* @author peida
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitColor {
/**
* 颜色枚举
* @author peida
*
*/
public enum Color{ BULE,RED,GREEN};
/**
* 颜色属性
* @return
*/
Color fruitColor() default Color.GREEN;
}
package annotation;
import annotation.FruitColor.Color;
public class Apple {
@FruitName("Apple")
private String appleName;
@FruitColor(fruitColor=Color.RED)
private String appleColor;
public void setAppleColor(String appleColor) {
this.appleColor = appleColor;
}
public String getAppleColor() {
return appleColor;
}
public void setAppleName(String appleName) {
this.appleName = appleName;
}
public String getAppleName() {
return appleName;
}
public void displayName(){
System.out.println("水果的名字是:苹果");
}
}
package annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 水果供应者注解
* @author peida
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitProvider {
/**
* 供应商编号
* @return
*/
public int id() default -1;
/**
* 供应商名称
* @return
*/
public String name() default "";
/**
* 供应商地址
* @return
*/
public String address() default "";
}
/***********注解使用***************/
public class Apple {
@FruitName("Apple")
private String appleName;
@FruitColor(fruitColor=Color.RED)
private String appleColor;
@FruitProvider(id=1,name="陕西红富士集团",address="陕西省西安市延安路89号红富士大厦")
private String appleProvider;
public void setAppleColor(String appleColor) {
this.appleColor = appleColor;
}
public String getAppleColor() {
return appleColor;
}
public void setAppleName(String appleName) {
this.appleName = appleName;
}
public String getAppleName() {
return appleName;
}
public void setAppleProvider(String appleProvider) {
this.appleProvider = appleProvider;
}
public String getAppleProvider() {
return appleProvider;
}
public void displayName(){
System.out.println("水果的名字是:苹果");
}
}
/***********注解处理器***************/
public class FruitInfoUtil {
public static void getFruitInfo(Class> clazz){
String strFruitName=" 水果名称:";
String strFruitColor=" 水果颜色:";
String strFruitProvicer="供应商信息:";
Field[] fields = clazz.getDeclaredFields();
for(Field field :fields){
if(field.isAnnotationPresent(FruitName.class)){
FruitName fruitName = (FruitName) field.getAnnotation(FruitName.class);
strFruitName=strFruitName+fruitName.value();
System.out.println(strFruitName);
}
else if(field.isAnnotationPresent(FruitColor.class)){
FruitColor fruitColor= (FruitColor) field.getAnnotation(FruitColor.class);
strFruitColor=strFruitColor+fruitColor.fruitColor().toString();
System.out.println(strFruitColor);
}
else if(field.isAnnotationPresent(FruitProvider.class)){
FruitProvider fruitProvider= (FruitProvider) field.getAnnotation(FruitProvider.class);
strFruitProvicer=" 供应商编号:"+fruitProvider.id()+" 供应商名称:"+fruitProvider.name()+" 供应商地址:"+fruitProvider.address();
System.out.println(strFruitProvicer);
}
}
}
}
1. 创建类的实例
2. 类的静态变量,或者为静态变量赋值
3. 类的静态方法
4. 使用类的反射机制强制创建某个类或接口对应的java.lang.Class对象
5. 初始化某个类的子类
6. 直接使用java.exe来运行某个主类
Class c=Class.forName("com.peng.Person"):
Constructor con=c.getConstructor(String.class,int.class);
Object obj=con.newInstance("张三",12);
1. 获取Class
2. 获取指定的构造方法
3. 暴力访问,通过setAccessible(true)方法
4. 通过构造方法类Constructor来创建对象
Class c=Class.forName("com.peng.Person");
Constructor con=c.getDeclaredConstructor(String.class,int.class);
con.setAccessible(true);
Object obj=con.newInstance("小明",12);
通过反射获取成员变量并使用
实例
Class c=Class.forName("com.peng.Person");
Fileds[] fileds=c.getDeclaredFileds();
for(Filed filed:fileds){
System.out.println(filed);
}
Filed temp=Class.forName("com.peng.Person").getFiled("age");
Class c=Class.forName("com.peng.Person");
Constructor con=c.getConstructor(String.class);
Object obj=con.newInstance("李四");
Filed filed_name=c.getFiled("name");
filed_name.set(obj,"王五");
filed_name.get(obj);
1. 获取Class对象
2. 获取构造方法
3. 通过构造方法,创建对象
4. 获取指定的方法
5. 执行找到的方法
Class c=Class.forName("com.peng.Person"); Constructor con=c.getDeclaredConstructor(String.class); Object obj=con.newInstance("赵六"); Method method1 = c.getDeclaredMethod("addPerson",int.class); method1.setAccessible(true);//暴力访问--private Object reslute=cmethod1.invoke(obj,12);将已存在的ArrayList中添加String数据(泛型的擦除)
1. 创建ArrayList对象 list
2. 往list对象中添加Integer对象
3. 获取ArrayList的Class
4. 获取add方法
5. 添加String数据
ArrayList list = new ArrayList();
list.add(1);
Class c=Class.forName("java.util.ArrayList");
//这里的Object.class保证可以添加任何对象
Method addMethod=c.getMthod("add",Object.class);
addMethod.invoke(list,"哈哈");
package com.peng.test;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Scanner;
/**
* @author kungfu~peng
* @data 2017年10月9日
* @description
*/
public class Demo1 {
public static void main(String[] args) throws Exception {
ArrayList list=new ArrayList();
list.add(1);
Class c=Class.forName("java.util.ArrayList");
Method me=c.getMethod("add", Object.class);
me.invoke(list, "hehge");
System.out.println(list);
}
}
1. Properties prop=new Properties();
2. prop.load(new FileInputStream("person.properties"));
3. String name=prop.getProperty("name");
1. Class对象
2. 构造函数创建对象
package testt;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* @author kungfu~peng
* @data 2017年10月10日
* @description
*/
public class Person {
private int age;
protected String name;
String sex;
public int id;
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(int age, String name, String sex, int id) {
super();
this.age = age;
this.name = name;
this.sex = sex;
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
// 方法
/**
* 功能: 返回值类型: 参数列表:
*/
private void add() {
System.out.println("add");
}
/**
* 功能: 返回值类型: 参数列表:
*/
protected void delete() {
System.out.println("delete");
}
/**
* 功能: 返回值类型: 参数列表:
*/
void update() {
System.out.println("update");
}
/**
* 功能: 返回值类型: 参数列表:
*/
public void query(int id) {
System.out.println("query");
}
// 测试
public static void main(String[] args) throws Exception {
// 获取Class对象
Class c = Class.forName("testt.Person");
// 获取构造方法
Constructor con = c.getConstructor(int.class, String.class,
String.class, int.class);
// 通过构造方法来创建对象
Object obj = con.newInstance(12, "aa", "bb", 23);
// 获取属性
Field id_Filed = c.getDeclaredField("id");
Field name_Filed = c.getDeclaredField("name");
Field sex_Filed = c.getDeclaredField("sex");
Field age_Filed = c.getDeclaredField("age");
name_Filed.setAccessible(true);
id_Filed.setAccessible(true);
sex_Filed.setAccessible(true);
age_Filed.setAccessible(true);
// 设置属性
id_Filed.set(obj, 100);
name_Filed.set(obj, "100");
sex_Filed.set(obj, "100");
age_Filed.set(obj, 100);
// 获取属性值
System.out.println(id_Filed.get(obj));
// 获取方法
Method me = c.getDeclaredMethod("add", null);
me.setAccessible(true);
me.invoke(obj, null);
}
}
静态代理是什么
若代理类在程序运行前就已经存在,那么这种代理方式被成为 静态代理 ,这种情况下的代理类通常都是我们在Java代码中定义的。 通常情况下, 静态代理中的代理类和委托类会实现同一接口或是派生自相同的父类。
//接口
public interface Sell {
void sell();
void ad();
}
//生产厂家
public class Vendor implements Sell {
public void sell() {
System.out.println("In sell method");
}
public void ad() {
System,out.println("ad method")
}
}
//微商代理
public class BusinessAgent implements Sell {
private Vendor mVendor;
public BusinessAgent(Vendor vendor) {
this.mVendor = vendor;
}
public void sell() {
mVendor.sell();
}
public void ad() {
mVendor.ad();
}
public void sell() {
if (isCollegeStudent()) {
vendor.sell();
}
}
}
动态代理是什么
例子
//静态代理--冗余代码
public class BusinessAgent implements Sell {
private Vendor mVendor;
public BusinessAgent(Vendor vendor) {
this.mVendor = vendor;
}
public void sell() {
System.out.println("before"); //冗余处
mVendor.sell();
System.out.println("after"); //冗余处
}
public void ad() {
System.out.println("before"); //冗余处
mVendor.ad();
System.out.println("after"); //冗余处
}
}
从以上代码中我们可以了解到,通过静态代理实现我们的需求需要我们在每个方法中都添加相应的逻辑,
这里只存在两个方法所以工作量还不算大,假如Sell接口中包含上百个方法呢?这时候使用静态代理就会编写许多冗余代码。
通过使用动态代理,我们可以做一个“统一指示”,从而对所有代理类的方法进行统一处理,而不用逐一修改每个方法。
例子
InvocationHandler接口
在使用动态代理时,我们需要定义一个位于代理类与委托类之间的中介类,这个中介类被要求实现InvocationHandler接口
public interface InvocationHandler {
Object invoke(Object proxy, Method method, Object[] args);
}
动态代理中的委托类:动态代理方式下,要求委托类必须实现某个接口,这里我们实现的是Sell接口。委托类Vendor类的定义如下:
public class Vendor implements Sell {
public void sell() {
System.out.println("In sell method");
}
public void ad() {
System,out.println("ad method")
}
}
中介类:上面我们提到过,中介类必须实现InvocationHandler接口,作为调用处理器”拦截“对代理类方法的调用。中介类的定义如下:
public class DynamicProxy implements InvocationHandler {
private Object obj; //obj为委托类对象;
public DynamicProxy(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before");
Object result = method.invoke(obj, args);
System.out.println("after");
return result;
}
}
public class Main {
public static void main(String[] args) {
//创建中介类实例
DynamicProxy inter = new DynamicProxy(new Vendor());
//加上这句将会产生一个$Proxy0.class文件,这个文件即为动态生成的代理类文件
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
Sell sell = (Sell)(Proxy.newProxyInstance(Sell.class.getClassLoader(), new Class[] {Sell.class}, inter));
//通过代理类对象调用代理类方法,实际上会转到invoke方法调用
sell.sell();
sell.ad();
}
}
直接通过属性的描述器java.beans.PropertyDescriptor类,来访问属性的getter/setter 方法;
public class Point {
private Integer x;
private Integer y;
public Point(Integer x, Integer y) {
super();
this.x = x;
this.y = y;
}
public Integer getX() {
return x;
}
public void setX(Integer x) {
this.x = x;
}
public Integer getY() {
return y;
}
public void setY(Integer y) {
this.y = y;
}
}
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
public class Reflect {
public static void main(String[] args) throws Exception {
Point point = new Point(2, 5);
String proName = "x";
getProperty(point, proName);
setProperty(point, proName);
}
private static void setProperty(Point point, String proName) throws Exception {
PropertyDescriptor proDescriptor = new PropertyDescriptor(proName, Point.class);
Method methodSetX = proDescriptor.getWriteMethod();
methodSetX.invoke(point, 8);
System.out.println(point.getX());// 8
}
private static void getProperty(Point point, String proName) throws Exception {
PropertyDescriptor proDescriptor = new PropertyDescriptor(proName, Point.class);
Method methodGetX = proDescriptor.getReadMethod();
Object objx = methodGetX.invoke(point);
System.out.println(objx);// 2
}
}
private static void getProperty(Point point, String proName) throws Exception {
BeanInfo beanInfo = Introspector.getBeanInfo(point.getClass());
PropertyDescriptor[] proDescriptors = beanInfo.getPropertyDescriptors();
for(PropertyDescriptor prop: proDescriptors){
if(prop.getName().equals(proName)){
Method methodGetx = prop.getReadMethod();
System.out.println(methodGetx.invoke(point));//8
break;
}
}
}