-1

I wrote a function to traverse an Android view and find all children of a given class. Had quite a bit of trouble, but with autocorrect, I finally got it working. The problem is that I don't understand why it works (always scary).

There are 2 things that throw me:

  1. Why is @SuppressWarnings("unchecked") required?
  2. What is the first <classType> in the method declaration called and supposed to do?

I'd prefer to understand my code than just blindly go with what works.

@SuppressWarnings("unchecked")
public <classType> ArrayList<classType> findChildrenByClass(Class<?> classType, ViewGroup viewGroup) {
  ArrayList<classType> returns = new ArrayList<classType>();
  View current_child;
  ArrayList<classType> new_children;

  if (viewGroup.getChildCount() > 0) {
    for (int i=0;i<viewGroup.getChildCount();i++) {
      current_child = (View)viewGroup.getChildAt(i);

      if (current_child.getClass().equals(classType)) {
        returns.add((classType)current_child);
      }

      if (current_child instanceof ViewGroup 
          && ((ViewGroup)current_child).getChildCount() > 0
          ) {
        new_children = findChildrenByClass(classType, (ViewGroup)current_child);
        returns.addAll(new_children);
      }
    }
  }

  return returns;
}

EDIT: To help others who were confused like me, this is the final revised version

public <T> ArrayList<T> findChildrenByClass(Class<T> classType, ViewGroup viewGroup) {
  ArrayList<T> returns = new ArrayList<T>();
  View current_child;
  ArrayList<T> new_children;

  if (viewGroup.getChildCount() > 0) {
    for (int i=0;i<viewGroup.getChildCount();i++) {
      current_child = (View)viewGroup.getChildAt(i);

      if (current_child.getClass().equals(classType)) {
        returns.add((T)current_child);
      }

      if (current_child instanceof ViewGroup 
          && ((ViewGroup)current_child).getChildCount() > 0
          ) {
        new_children = findChildrenByClass(classType, (ViewGroup)current_child);
        returns.addAll(new_children);
      }
    }
  }

  return returns;
}
  • 1
    http://docs.oracle.com/javase/tutorial/java/generics/ – Oliver Charlesworth Feb 10 '14 at 18:21
  • possible duplicate of [Java Generics](http://stackoverflow.com/questions/490091/java-generics) – Oliver Charlesworth Feb 10 '14 at 18:22
  • More specifically: http://docs.oracle.com/javase/tutorial/extra/generics/methods.html – Cruncher Feb 10 '14 at 18:23
  • Can't you just discard your `Class > classType` parameter? I can't see it being used anywhere. – Keppil Feb 10 '14 at 18:24
  • @Keppil Maybe. The goal was to execute a function that answered the question, "What are all the objects in a view of a given class?" The classType parameter was how I defined "of a given class." Am I being dumb? –  Feb 10 '14 at 18:41
  • Ah, nm, it is used there. Well, perfect example of why you shouldn't use the same name for different things. :) – Keppil Feb 10 '14 at 18:43
  • @Keppil Fair enough... I didn't know they were any different, hence the question. :) –  Feb 10 '14 at 19:01

4 Answers4

1

Suppress warnings is to not report warnings that the compiler will bring up, like unused variables or depreciated methods.

Suppress warnings is not required and your program should still work.

< classType > are generics. Read up on generics but basically typing a parameter.

In your case, the first Class type is the return type if you want to return something. If you do not want to return anything then use void.

Springy
  • 588
  • 5
  • 15
1

@SuppressWarnings("unchecked")

This is simply to remove warnings from the compiler, for example, the compiler may warn you of unused variables, possible NullPointerExceptions, deprecated methods, etc. This tells the compiler not to warn about this things. Usually you do this because you don't care about the warning when for example you are using some deprecated method.

classType

That's what we call Java Generics, you can read a complete explanation here. Basically they allow you to create generic Classes. For example ArrayList<> is a generic class you can use the list with whatever object you want so you don't have to write a complete new implementation for each data type you want to store:

ArrayList<Object>
ArrayList<String>
ArrayList<Integer>
Andres
  • 6,080
  • 13
  • 60
  • 110
1
  1. @SuppressWarnings("unchecked") is an annotation that silences certain class of compiler warnings in the method, for example casting a superclass object to a subclass type without first checking for compatibility with instanceof, e.g. (classType)current_child. The purpose of these warnings is to find potential ClassCastExceptions and other problems at compile time.

  2. classType is used in two, slightly confounded roles in your code. First it's a generic type argument in <>. Search for "java generics" for more information. Additonally it's an argument name in Class<?> classType which is different from the generic type argument.

laalto
  • 150,114
  • 66
  • 286
  • 303
0

The "classType" is probably a declaration on your class instance something like:

public class MyClass{

private T classType;

}

That means you will store a class to use as reference, in your case you use to identify the childrens.

The supressed warning is needed bcs you don't have a way to make sure the type is the right when you cast without checking the instance...

GhostDerfel
  • 1,533
  • 1
  • 11
  • 18