java 语法机制

语法
八个基本变量

  • 整型
    byte,short,int,long
  • 浮点型
    float,double
  • 布尔型
    boolean
  • 字符型
    char

引用类型/包装类型

  • Integer
    默认为null
  • string

功能上可以扩展,如方便互相转换
java还是以类为基础的,操作参数大都为object类型。
object更普适,允许null
如集合对象-List,数据库返回类型

同时包类型和基本类型是自动装箱,拆箱。

比较
"=="
基本数据时,比较的是值
引用类型时,比较的是内存地址。也就是同一个对象实例。
当String s1="xx",String s2="xx"时,
原来理解是引用类型,那应该地址不一样。
但这里说是常量是有专门一块内存区域。
分配时,当该区域已经有一样值时,返回该值地址。
所以比较结果一样

当String s1=new String("xx")时
就是在堆中分配地址给xx
结果就不一样

equals
这个是Objcet中的就有的方法,
各个类会重写。
引用类基本会重写成比较包含的值是否相同
如Integer,String

所以比较值要用equals。

转换

String->Integer
Integer.valueOf(String)

Integer->String
Integer.toString()
String.valueOf()

数组
type []
Arrays数组的工具类

Arrays.copyOfRange(int[] original, int from, int to)-复制
Arrays.toString()
Arrays.sort()--排序

集合
arrayList
set--数据不重复,一般用HashSet实现类
map--键值映射,这个Key也是不重复的,一般用HashMap实现类

map->set setA.addAll(hashMapA.values());

collection->Iterable(Iterator/迭代器)
是一个接口。集合都是实现这些接口的,
才能foreach都适用?

转化
array->List

(java.util.Arrays)List list = (java.util.Arrays.ArrayList)Arrays.asList(strArray);
这种转出来的List不是同一个基类,没有add(),remove()等方法。适用于读取。  

ArrayList<String> list = new ArrayList<String>(Arrays.asList(strArray))   

list->array

String[] array2 = testList.toArray(new String[testList.size()]);

这里应该也有那种从'符号分隔的字符串',数组,集合的那种上下转换链。

Stream
不知道咋形容,属于Lambda那一类的函数式?功能流水式,转换特别强。
不是以前那种文件流,网络流这种操作byte,和list类似都是对象实例。

粗略比较,一种是把东西拿过去,处理好后拿回来,一种是把操作方法拿过来执行。

惰性实时计算

Stream<BigInteger> naturals = createNaturalStream(); // 不计算
Stream<BigInteger> s2 = naturals.map(BigInteger::multiply); // 不计算
Stream<BigInteger> s3 = s2.limit(100); // 不计算
s3.forEach(System.out::println); 
  • map
    传入一种转换方法,返回转换后的数据。
  • filter
  • reduce
  • collect

数组转入
Arrays.stream()

转出list
collect(Collectors.toList())

转出Array
toArray()

String[] imei
List<NameValuePair> nameValuePairs = Arrays.stream(imei).map(item -> {
            return new BasicNameValuePair("devices[]", item);
        }).collect(Collectors.toList());

各种集合混合处理。。
从一个字符数组,转成stream,map成内容变为obj,再转成list。

函数
同名函数--方法重载

参数不能设置默认值。
可以再写一个同名函数中继下,里面写上调用的默认值。

 private String ctrl(String imei, String type ) {
        return ctrl(imei,  type,"",null) ;
    }

隐式函数
实例方法隐含地传入了一个this变量。

private double salary;  
public void ariseSalary(double em){  
    double employ = this.salary * em;  
    this.salary += employ;  //这部分操作的就是该类的实例域salary
}  

这里this也可以不用些,js中都要写上this

参数中有三个点
表示可变长度的参数,类似于一个数组,不一样的是可以不传。。


Object是原类,所有类的基础。
如果没有指明extends父类。自动从Object继承。
一些概念在mix language记录

构造流程
有三块

  • A-静态语句块
    static{}
  • B-实例化代码块
    直接{}里面写
  • C-构造代码块
    classname()
    {
    }

A只会执行一次,不论这个类被new 了几个实例。第一个执行。
B,C每次new都会执行。B会在C之前执行。
B,C执行时能调用类里面的方法,访问属性。
这个感觉和印象中其它语言不同,好像都是new好了以后才能调用方法。
可能由于已经在静态语句块那一环已经初始化过了吧。

全局参数这个用到static{}

泛类型 <>
https://blog.csdn.net/qq_27093465/article/details/73229016
很多类只是数据类型不同,规则是一样的,需要一个通用的类型作为参数。
有点像可以装不同头的扳手。

java本身类型都是从Object继承的,为啥不直接用object作为参数。
主要是object太通用了,输入输出都是不确定的,每个地方都需要强制转化,类型错了,编译时也没法判断。

ObjectPoint integerPoint = new ObjectPoint();  
integerPoint.setX(new Integer(100));  
Integer integerX=(Integer)integerPoint.getX();  

泛型相对来说,定义的时候是通用类型,但实例化时是用确定的类型,这样在编译时输入输出都相当于确定类了。

泛型的代表字母

  • E — Element,常用在java Collection里,如:List<E>,Iterator<E>,Set<E>
  • K,V — Key,Value,代表Map的键值对
  • N — Number,数字
  • T — Type,类型,如String,Integer等等

泛型可以用在类,接口,也可以用在函数

Class<T>
Class<?>
https://segmentfault.com/a/1190000039835272

  • 实例化的时候

<T>实例化时要指定一个具体类型List<Number>

<?>不需要指定类型
List<?> list = new ArrayList<Integer>();
list = new ArrayList<Number>();

也没看出有啥用处

  • 定义的时候
    代码里不涉及具体的类型。
Set<?> s1
for (Object o : s1)

引用时用基类Object表示就行。
那和定义Set<object> s1 有啥区别。可能Set<>既能填T,也能填?..

记得c++模板其实是底层每种类型都实现一遍。

  • 不涉及具体的类型操作,只是一些规则流程性的代码,输出跟着输入类型就行。
     public interface FuncCtrl<T> {
      T getCommand(String product);
     }
     public class MonitorFuncCtrl implements FuncCtrl<MonitorFunction.Command> 
     Interface Command {}
     输入输出都时接口
    
  • 要处理具体类型的计算,类型集合先实现好,再根据输入类型来调用。
    类型是无法穷举的,也是根据业务来定义可能的几种。
    TypeConverter
     regist(Integer.class, new IntegerConverter());
     regist(int.class, new IntegerConverter());
     ...
     各种类型的处理方法加入converterMap
     
     IConverter<?> converter = converterMap.get(type);
    
    
  • 大部分时候都是在系统已有的泛型类上再去操作,底层已经实现好各类型?

public <T> T get(Object key) {}
可能看不懂这个含义,把<T>忽略,就是返回一个T类型的值。

大概有几种形式。

  • 类似ArrayList,实例化时参数传入类型
  • 继承某个类时,传入类型。

泛型往往和反射相关联

这里的实现机制叫擦除,会把类型信息抹掉。

String userString = "[{\"userId\":\"111\",\"userName\":\"Tom\"},{\"userId\":\"222\",\"userName\":\"Jerry\"}]";
List<UserInfo> input = new ArrayList<>();
List<UserInfo> userInfoList = JSON.parseObject(userString, input.getClass());

这样只能知道是个List,里面是什么类型得不到的。
同时这个泛型是作为一个附加信息来传递的。
就要另外传递类型进去。

List<UserInfo> userInfoList = JSON.parseObject(userString, new TypeReference<List<UserInfo>>() {});

这里就比较迷惑,为了传递类型又弄了个泛型类,类似下面的机制获得。
那为啥input不直接getGenericSuperclass。
感觉只能是该类继承某个泛型父类时指定类型,属于类里面的信息。
直接实例化时传入类型是不行的。
ArrayList里面应该是能获取到类型的。

https://blog.csdn.net/lvxiangan/article/details/94836504
当一个类继承了某个泛型类,getSuperclass也是一样道理,

public class Person<T> {}

public class Student extends Person<Student>
 Student st = new Student();
 Class clazz = st.getClass();
 Type type = clazz.getGenericSuperclass();--这个是所有类型的信息更全的接口了。
 ParameterizedType p = (ParameterizedType)type;--泛型类型的接口
 Class c = (Class) p.getActualTypeArguments()[0]--取参数数组的第一个。

匿名类
定义类的最终目的是创建一个类的实例,但是如果某个类的实例只是用一次,则可以将类的定义与类的实例化,放到与一起完成.
必须继承一个父类或者实现一个接口。

  HelloWorld frenchGreeting = new HelloWorld() {
    String name = "tout le monde";
    public void greet() {
        System.out.println("Salut " + name);
    }

};

前面就和实例化一样的,后面直接跟了{},里面写类的定义。
原先的流程是要弄一个类名,再定义这样吧。

private void retrofitExecute() {
new Thread(new Runnable() {}).start();
}

进一步实例名称也没有了。

new Thread((Runnable)()->{})

idea显示时又给简化了变成这个箭头。实际代码是上面这样。

感觉java都是用类做载体,缺少更轻量的结构体,也没有函数回调传递。就算只是一个方法也得弄成类或者接口。写起来会很繁琐。

内部类
一个类定义在另一个类的内部,这个类就是Inner Class

然后这里有个叫匿名内部类的,感觉比较混乱,有说就是匿名类的别称。。

函数式/Lambda
虽然是一种底层独立的范式,但在这里和匿名类结合的很紧密。
有一大堆单方法的接口,用匿名类简化后,也还是繁琐。
用lamba又简化了很多。基本只要写最后实际的回调代码

然后lambda是后面引进的,并不是啥地方都能用。

首先着这个函数传进去是对应哪个接口函数的。
没有函数名,只能是一个单方法的接口,或者只有一个抽象方法的接口。

这个接口用注解@FunctionalInterface标记

里面内容也很多

这个比较综合,泛类型这些都会涉及。

主要的几种用法

                                  输入        返回
Consumer<T>--消费型接口             T           / 
Supplier<T>--供给型接口             /           T
Function<T,R>--处理返回型接口       T           R
Prodicate<T>--断定型接口            T           Bool.

这些都是预先定义在java.util.function,看着就是一些正常的接口
public interface Consumer<T>
里面其实也包含多个函数的,但除了一个要实现的函数,其它都是有default默认实现的。

编写函数式风格。

  • 先要申明一个接口,这里已经有模板了。
  • 申明函数时参数填上述接口 Fun(Function<Record,FuncResult> proc)
    这里应该泛型参数应该是要实例化类型的,
    stream.map这种不指定类型的,Function<? super T, ? extends R> 是用?通配符
    函数里面调用resp=proc.apply(record)
  • 调用的时候就可以 Fun(record->{process,return FuncResult})

接口的实例化
Function<Integer, Integer> times2 = i -> i*2; 看着挺怪的。。

然后Function里还有一些其它函数。compose,andThen这些
这些可以用来嵌套加入处理逻辑。
https://blog.csdn.net/anLA_/article/details/78191494

大致就是用在集合类型。然后stream是原生就是lambda设计。

有种双冒号 (::)的写法,更是简洁到只剩下方法名了
https://blog.csdn.net/zhoufanyang_china/article/details/87798829
叫方法引用。
map(Integer::valueOf)

单继承/多接口
extends xxx
implements xxx,xxx,xxx
public Thread(Runnable targer)此构造方法接受Runnable的子类实例..

接口定义
public interface OnRefreshListener {
public void onRefresh();
}

接口实现
implements SwipeRefreshLayout.OnRefreshListener
重载接口函数
@Override
public void onRefresh() {
    Log.d("Swipe", "onRefresh");
    retrofitCallBack();
}

全局类

  classA
   staic  classA instance
   static ClassA getInstance()
   { 
      if instance==null
      {
            instance=new classA
        }
       return instance
    }
    也有 synchronized (classA.class) {nstance=new classA}
    
    

这样获取到的都是同一个实例。

也有

class TableMapping
private static TableMapping me = new TableMapping(); 
public static TableMapping me() {
		return me;
}

**级联调用**  
类似Jquery这种可以流水式的一直配置下去  
方法内部通过返回this,
Obj.setA().setB()....



**静态/static**  
* 属性--是放在一个单独的静态控件里,不属于实例空间。可以直接访问。  
   所以也不是线程安全的。
* 方法--静态方法属于class不属于实例,无法访问this,实例属性。  
* 类-只有内部类可以声明静态。
  * 内部类--java一个文件只能是一个public类,有时候一个模块内部比较复杂,需要建几个类,但这些类不需要被其它模块用,建文件存放冗余。
  * 静态内部--可能是作为辅助类,功能是比较独立的,而不是要通过外部类实例化后再去用。
   lamp系统中用于内部的数据结构,

interface/接口

能两层结构  
public interface LedFunction {
    public interface Response {
      xx
}}

能继承
public interface Command extends LedFunction.Command

可以import 类中的方法。。
import static com.hc.lamp.config.rabbitmq..RabbitPluginsend;

可以定义一个默认实现
default void eat(){
        System.out.println("eat");
    }

instanceof
判断obj是否为某个类的实例/是否是某个接口的实现

ThreadLocal
会需要一个静态的空间,但不同线程要区隔开。

private static final ThreadLocal<String> local = new ThreadLocal<>();

看着是一个静态的map集合,这样里面就能放各自线程的值。

结构体
有些属性直接public propertyA
有些属性是private ,然后用public set,get 方法读写

枚举值
限定了范围,名称和值一体。以前常用来比较的时候直接看出含义。==EnumA.MON

这里看着丰富一些。

说其实是一个枚举类,在类的机制上加入了自己的机制。
编译出来后大概是

public final class Color extends Enum { // 继承自Enum,标记为final class
    // 每个实例均为全局唯一:
    public static final Color RED = new Color();
    public static final Color GREEN = new Color();
    public static final Color BLUE = new Color();
    // private构造方法,确保外部无法调用new操作符:
    private Color() {}
}

每个枚举值都是一个实例。

有用类静态属性的,这是干啥?两者没啥关系,只是说把枚举值的序号再定义下。

class nameA{
    static int propertya=1; 
    static int propertyb=2; 
    }

public enum typea{
   propertya,
   propertyb}

定义属性,方法。
这里拓展成像类一样,调用里面的函数。
变成类似字典类型的用法。

 enum Product {
        HUIDU("HUIDU"), XIXUN("XIXUN"), MOCK("MOCK"), HC("HC");
        Product(String value) {
            this.product = value;
        }

        private final String product;

        public String getProduct() {
            return product;
        }
    }
    
Product.HUIDU;
Product.HUIDU.getProduct();

Enum的一些方法
可以直接有==比较
name()--获得这个枚举值的字符名称
valueOf(String)--将字符名称转为枚举值
ordinal()--序数,从0开始

两个花括号
这还挺绕的。。。
两个花括号是拆开看的。
第一个花括号是生成匿名类,
第二个花括号是这个匿名类里面的构造流程中的实例化代码块。

new JSONObject() {{
       put("userName", username);
       put("password", password);
    }}

这里put是JSONObject里面定义好的函数。
感觉用来初始化类里的一些数据。

异常处理
函数抛出异常
throw new HcException("没有节目信息");
如果调用者没有处理,那么控制台直接报错,程序退出。

 

反射
http://blog.csdn.net/lfsf802/article/details/7239652

getDeclaredConstructor 获取构造函数
http://hold-on.iteye.com/blog/1906731

InjectBean
字符串<-->调用

字符串-->类
clazz=Class.forName("xx.classname")

字符串-->方法

 Method method=clazz.getMethod("methodname", String[].class);
 method.invoke(clazz,argvalue) 

这里遍历方法的时候,对于参数也要有个转换

 Class<?>[] types = method.getParameterTypes();
 object argvalue=convert(types[0], paraValue)
 这里用了泛型。

熟悉这些要对java的原始类型比较熟悉,
class java.lang.String
interface java.util.Map

annotation/注解
注解是专门有个注解类的。public @interface ax。需要实现申明。
注解类有特殊的属性定义

@Target  
   ElementType.TYPE:能修饰类、接口或枚举类型
   ElementType.METHOD:能修饰方法
   ElementType.FIELD:能修饰成员变量
   ......
@Retention
RetentionPolicy.SOURCE: 注解只在源代码中存在,编译成class之后,就没了。@Override
RetentionPolicy.CLASS: 注解在java文件编程成.class文件后,依然存在,但是运行起来后就没了。@Retention的默认值
RetentionPolicy.RUNTIME: 注解在运行起来之后依然存在,程序可以通过反射获取这些信息
@Inherited
@Documented
@Repeatable 

被标记后用法
MyTable myTable= (MyTable) clazz.getAnnotation(MyTable.class)
myTable.name();
成为一个标记类。

一般会用的组合Retention-RUNTIME,@Target-TYPE/METHOD/FIELD
一般的用处

  • 标记作用
    申明@interface中没有属性定义。只用@interface的名字
    用的时候m.getAnnotation(MyId.class)!=null来判断有无标记。
  • 有参数控制
    申明@interface中定义属性。
    标记时@MyTable(name="hero_"),设置好值。
    调用时标记类的用法。
  • 类的自动注入
    https://blog.csdn.net/qq_24871519/article/details/85066838
    属性有两种情况
    • 属性是类,只需标注,
    • 属性是接口,那就需要传入实现类。
      大致流程
      遍历属性 --getDeclaredFields。
      判断是否有相关标记
      对该属性值的设置。-declaredField.set(xx);

这里有几个关键点。

  • 这个是在何时,何地执行的
    类的创建肯定要被外部代理才能解析这些注解。
    类的托管,这里就涉及到spring这些容器的实现机制了。 https://fzsens.github.io/spring/2018/09/02/spring-framework-03/
    感觉是通过扫描包,然后可以把类加到容器里去。然后这个类的生命周期就由spring来管理。
    然后这个类的调用也不是显式的,是被管线所调用。
  • 注解类的动态创建。
    反射啥的
    这里就是AOP,IOC这些的应用,还是没转的过来弯。
    以往的类就一个创建步骤,现在已经演变出了生命周期。
    看着也就是省略了类的实例化过程。。

Thread
Thread/Runnable
简单用Runnable就行,Thread可能涉及方面多。
涉及--资源共享,继承的灵活性。。

和主线程的同步
https://www.jianshu.com/p/128476015902
CountDownLatch
主线程等子线程都完成后,再继续执行。完成的依据是一个计数器,计数量是线程的数量
主线程等待 --await()
子线程完成后减计数器-- countDown()
RemoteService

synchronized
同一时刻只有一个方法可以进入到临界区。
每一个对象都可以作为锁。
这里主要是锁的对象各式各样,锁对象,锁方法,锁类。看是否静态。

 

web请求处理

数据格式

  • x-www-form-urlencoded
    getParameter()
  • form-data
    要用request.getInputStream()或request.getReader()
    raw
  • request.getReader()
    jfinal中包装成getRawData
    一般都是Json格式,用JsonObj来转换

request.getParameter()、request.getInputStream()、request.getReader()这三种方法是有冲突的,因为流只能被读一次。

Map<String, String[]> paraMap = request.getParameterMap();

这里value是数组,是因为传入的参数中可能key值会有一样的。
如keya=v1&keya=v2 ,checkbox也是
单个key获取的话用String[] getParameterValues

posted @ 2023-05-16 17:42  shijianbo  阅读(22)  评论(0)    收藏  举报