小编Gho*_*ica的帖子

使用try/catch防止应用程序崩溃

我一直在研究一款try/catch经常使用的Android应用程序,以防止它甚至在没有必要的地方崩溃.例如,

xml layout带有的视图id = toolbar引用如下:

// see new example below, this one is just confusing
// it seems like I am asking about empty try/catch
try {
    View view = findViewById(R.id.toolbar);
}
catch(Exception e) {
}
Run Code Online (Sandbox Code Playgroud)

整个应用程序都使用此方法.堆栈跟踪没有打印,很难找到出错的地方.应用程序突然关闭而不打印任何堆栈跟踪.

我让我的大四学生向我解释,他说,

这是为了防止生产中的崩溃.

我完全不同意它.对我而言,这不是阻止应用程序崩溃的方法.它表明开发人员知道他/她在做什么,并且有疑问.

这是行业中使用的方法,以防止企业应用程序崩溃?

如果try/catch是真的,那么我们真的需要可以附加一个带有UI线程或其他线程的异常处理程序并捕获所有内容吗?如果可能的话,那将是更好的方法.

是的,空try/catch是坏的,即使我们将堆栈跟踪或日志异常打印到服务器,try/catch在所有应用程序中随机包装代码块对我来说没有意义,例如当每个函数都包含在a中时try/catch.

UPDATE

由于这个问题引起了很多关注,有些人误解了这个问题(也许是因为我没有明确表达过),我将把它改写一下.

这是开发人员在这里做的事情

  • 一个函数被编写和测试,它可以是一个小函数,它只是初始化视图或复杂的视图,在测试后它被包裹在try/catch块中.即使是永远不会抛出任何异常的函数.

  • 这种做法在整个申请中使用.有时会打印堆栈跟踪,有时只会出现debug log一些随机错误消息.此错误消息因开发人员而异.

  • 使用这种方法,应用程序不会崩溃,但应用程序的行为变得不确定.甚至有时候很难跟上出错的地方.

  • 我一直在问的真正问题是; 为了防止企业应用程序崩溃,业界是否遵循这种做法?而且我不是在询问空的try/catch.是不是,用户喜欢不会比意外行为的应用程序崩溃的应用程序?因为它真的归结为崩溃或用空白屏幕呈现用户或行为用户不知道.

  • 我在这里发布了一些真实代码的片段

      private void …
    Run Code Online (Sandbox Code Playgroud)

java android design-patterns coding-style try-catch

77
推荐指数
5
解决办法
2万
查看次数

为什么Map.of不允许空键和值?

在Java 9,新的工厂方法已经出台了List,SetMap接口.这些方法允许使用一行中的值快速实例化Map对象.现在,如果我们考虑:

Map<Integer, String> map1 = new HashMap<Integer, String>(Map.of(1, "value1", 2, "value2", 3, "value3"));
map1.put(4, null);
Run Code Online (Sandbox Code Playgroud)

如果我们这样做,上面是允许的,没有任何例外:

Map<Integer, String> map2 = Map.of(1, "value1", 2, "value2", 3, "value3", 4, null );
Run Code Online (Sandbox Code Playgroud)

它抛出:

Exception in thread "main" java.lang.NullPointerException
    at java.base/java.util.Objects.requireNonNull(Objects.java:221)
..
Run Code Online (Sandbox Code Playgroud)

我无法得到,为什么在第二种情况下不允许.

我知道HashMap可以将null作为键和值,但为什么在Map.of的情况下受限制?

同样的事情发生在的情况下java.util.Set.of("v1", "v2", null)java.util.List.of("v1", "v2", null).

java java-9

60
推荐指数
7
解决办法
1万
查看次数

使用BigDecimal作为货币的一个现实例子明显优于使用double

我们知道使用double货币是容易出错的,不推荐使用.但是,我还没有看到一个现实的例子,BigDecimal虽然double失败了,但不能通过一些舍入来简单地修复.


注意琐碎的问题

double total = 0.0;
for (int i = 0; i < 10; i++) total += 0.1;
for (int i = 0; i < 10; i++) total -= 0.1;
assertTrue(total == 0.0);
Run Code Online (Sandbox Code Playgroud)

不计算,因为它们通过舍入(在这个例子中从0到16的小数位的任何东西)都可以解决.


涉及总结大值计算可能需要一些中间圆棒,但由于流通总货币之中USD 1e12,爪哇double(即标准IEEE双精度其15个十进制数字)仍然是足够美分事件.


涉及分工的计算通常是不精确的,即使是BigDecimal.我可以构造一个不能用doubles 执行的计算,但可以BigDecimal使用100的标度执行,但它不是你在现实中可以遇到的东西.


我没有声称这样一个现实的例子不存在,只是我还没有看到它.

我也肯定同意,使用double更容易出错.

我正在寻找的是如下方法(根据Roland Illig的回答)

/** 
  * Given an input which has three decimal …
Run Code Online (Sandbox Code Playgroud)

java floating-point currency biginteger

44
推荐指数
5
解决办法
6806
查看次数

是否允许/建议重用收集器?

我的代码中有很多地方可以:

someStream.collect(Collectors.toList())
Run Code Online (Sandbox Code Playgroud)

其中,Collectors.toList()创建于每次使用一个新的收藏家.

这引出了一个问题:是否允许和建议做以下事情:

private final static Collector<…> TO_LIST = Collectors.toList()
Run Code Online (Sandbox Code Playgroud)

对于我使用的每种类型,然后使用单个收集器,如:

someStream.collect(TO_LIST)
Run Code Online (Sandbox Code Playgroud)

当需要收藏家时

由于收藏家是无国籍的,只是一系列功能和特征,我认为它应该有效,但OTOH,每次通话都会Collectors.toList()创造一个新的CollectorImpl<>.

重用收集器的缺点是什么?

java collections java-8 java-stream

44
推荐指数
4
解决办法
2944
查看次数

Java泛型:通配符<?> vs类型参数<E>?

我正在刷新我对Java泛型的知识.所以我转向Oracle的优秀教程......并开始为我的同事准备一份演示文稿.我在教程中遇到了关于通配符的部分,其中说:

考虑以下方法,printList:

public static void printList(List<Object> list) {
...
Run Code Online (Sandbox Code Playgroud)

printList的目标是打印任何类型的列表,但它无法实现该目标 - 它只打印一个Object实例列表; 它不能打印List<Integer>,List<String>,List<Double>,等等,因为它们不是的亚型List<Object>.要编写通用的printList方法,请使用List<?>:

public static void printList(List<?> list) {
Run Code Online (Sandbox Code Playgroud)

我明白这是List<Object>行不通的; 但我把代码更改为

static <E> void printObjects(List<E> list) {
    for (E e : list) {
        System.out.println(e.toString());
    }
}
...
    List<Object> objects = Arrays.<Object>asList("1", "two");
    printObjects(objects);
    List<Integer> integers = Arrays.asList(3, 4);
    printObjects(integers);
Run Code Online (Sandbox Code Playgroud)

你猜怎么着; 使用List<E>我可以打印不同类型的列表没有任何问题.

长话短说:至少教程表明需要通配符来解决这个问题; 但如图所示,它也可以通过这种方式解决.那么,我错过了什么?!

(旁注:用Java7测试;所以这可能是Java5,Java6的一个问题;但另一方面,Oracle似乎在他们的教程更新方面做得很好)

java generics

41
推荐指数
3
解决办法
9307
查看次数

MOCKITO:它是什么,它和Junit有什么不同?

我想知道Mockito是什么?

它是支持Junit还是编写Junit测试用例的环境?

有人可以解释一下Junit和Mockito之间的区别吗?

testing junit unit-testing mocking mockito

37
推荐指数
3
解决办法
3万
查看次数

为什么ArrayLists的ArrayList不是多维的?

我最近出现在面试中,面试官问我一个关于Arrays和的问题ArrayList.

他问我,如果一个数组的数组可以是多维的,那么,为什么是ArrayListArrayList"不是多维?

例如:

// Multidimensional
int[][] array = new int[m][n]; 

// Not multidimensional
ArrayList<ArrayList<Integer>> seq = new ArrayList<ArrayList<Integer>>(); 
Run Code Online (Sandbox Code Playgroud)

任何人都可以帮我理解这个吗?

java arrays list arraylist multidimensional-array

34
推荐指数
5
解决办法
4281
查看次数

Java int内存使用情况

当我在思考各种类型的内存使用情况时,我开始对Java在传递给方法时如何利用内存的整数感到困惑.

说,我有以下代码:

public static void main (String[] args){
     int i = 4;
     addUp(i);
}

public static int addUp(int i){
     if(i == 0) return 0;
     else return addUp(i - 1);         
}
Run Code Online (Sandbox Code Playgroud)

在下面的示例中,我想知道我的以下逻辑是否正确:

  • 我最初为整数i = 4创建了一个内存.然后我将它传递给一个方法.但是,由于原语未在Java中指向,在addUp(i == 4)中,我创建另一个整数i = 4.然后,还有另一个addUp(i == 3),addUp(i == 2), addUp(i == 1),addUp(i == 0),其中每次,由于未指向该值,因此在内存中分配新的i值.
  • 然后对于单个"int i"值,我使用了6个整数值存储器.

但是,如果我总是通过数组传递它:

public static void main (String[] args){
     int[] i = {4};
     // int tempI = i[0];
     addUp(i);
}

public static int addUp(int[] i){
     if(i[0] == 0) return 0;
     else return addUp(i[0] …
Run Code Online (Sandbox Code Playgroud)

java memory arrays int jvm

33
推荐指数
5
解决办法
4269
查看次数

Java中的'this'变量实际上是如何设置为当前对象的?

考虑:

class TestParent{
  public int i = 100;
  public void printName(){
    System.err.println(this); //{TestChild@428} according to the Debugger.
    System.err.println(this.i); //this.i is 100.
  }
}

class TestChild extends TestParent{
  public int i = 200;
}

public class ThisTest {
  public static void main(String[] args) {
    new TestChild().printName();
  }
}
Run Code Online (Sandbox Code Playgroud)

我知道有类似的问题已被提出,但我无法对Java中的'this'变量有一个明确的理解.

让我试着解释一下我是如何理解上面图像的结果的.

  1. 因为它是一个new TestChild()调用printName()方法thisTestChild对象,所以根据调试器,第6行中的变量被设置为一个对象 - {TestChild @ 428}.

  2. 但是,由于Java没有虚拟字段 - 我不完全确定这意味着什么,但我从概念上理解它与Java方法相反,它支持多态性 - 在编译时this.i设置为100 TestParent.

  3. 所以不管是什么this,this.i在一个TestParent方法中总是会i …

java oop this-keyword

30
推荐指数
2
解决办法
3461
查看次数

如何从“设置/地图”中删除多个元素并知道删除了哪些元素?

我有一种方法必须Set<K> keysToRemove从一些(可能大)中删除(小)中列出的任何元素Map<K,V> from。但是removeAll()不这样做,因为我需要返回实际上已删除的所有键,因为映射可能包含或可能不包含需要删除的键。

老式的代码很简单:

public Set<K> removeEntries(Map<K, V> from) {
    Set<K> fromKeys = from.keySet();
    Set<K> removedKeys = new HashSet<>();
    for (K keyToRemove : keysToRemove) {
        if (fromKeys.contains(keyToRemove)) {
            fromKeys.remove(keyToRemove);
            removedKeys.add(keyToRemove);
        }
    }
    return removedKeys;
}
Run Code Online (Sandbox Code Playgroud)

使用流写的相同:

Set<K> fromKeys = from.keySet();
return keysToRemove.stream()
        .filter(fromKeys::contains)
        .map(k -> {
            fromKeys.remove(k);
            return k;
        })
        .collect(Collectors.toSet());
Run Code Online (Sandbox Code Playgroud)

我发现这更加简洁,但是我也发现lambda太笨拙了。

任何建议如何以较少笨拙的方式实现相同结果?

java lambda java-stream

29
推荐指数
3
解决办法
1458
查看次数