I used dex2jar to get jar from an apk and to view it used JD-GUI .
But I notice there are label symbols such as following,
if (this.data.length != 7)
break label279;
// more code here
label279: short[] aos = { 0, 0 };
is it something added by compiler(or Obfuscate) ? is there any other tool that could use to avoid these labels?
If found this
https://code.google.com/p/dex2jar/source/browse/dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/CleanLabel.java?r=e8b872fdfce8a5a39aa7df083c46ec724fa8d3f4
is it something relate for this cleaning ?
Further research:
if (Math.abs(k) > this.mMaxRotationAngle)
if (k >= 0)
break label100;
label100: for (k = -this.mMaxRotationAngle; ; k = this.mMaxRotationAngle)
{
transformImageBitmap((ImageView)paramView, paramTransformation, k);
break;
}
From the above code by natural observation I changed the code to :
if (Math.abs(k) > this.mMaxRotationAngle)
// label100:
for (k = -this.mMaxRotationAngle; ; k = this.mMaxRotationAngle)
{
if (k >= 0)
break;// label100;
transformImageBitmap((ImageView)paramView, paramTransformation, k);
// break;
}
Still the label100 remains as a mystery... Wondering how does dex2jar handles the situations when it is unaware of the code.
the existence of : operator also suggests that there might be a for each loop
If at some point in future this mystery is resolved then please notify me too.
thanks.
Related
I am very new to Java (doing a beginners university module) so sorry for the probably silly question. I am trying to verify whether a ragged array is a 'tridiagonal matrix'.
It is valid if it is of length 3 at the first level and of length n − 1, n, and n − 1 at the second level. I intended to come up with a code to firstly verify the length is 3, then find the longest length array within it for n, then finally verify each length.
For whatever reason my code won't compile but I'm not seeing an error message, just a red exclamation mark on the class. I assume this means there are multiple errors. If anyone could point them out it would be a massive help.
static boolean isValidTridiagonal ( double [][] m)
{
if (double [][]=new double [3][])
{
int n = 0;
for(int i = 0; i < m.length; i++)
{
if(m[i].length > n)
{
n = m[i].length;
if( (m[0].length = n-1) && (m[1].length = n) &&(m[2].length=n-1))
{
return true
}
else
{
return false
}
}
else
{
return false
}
}
Thanks very much!
I agree with Foolish in the comments that it's helpful to use an IDE that can highlight syntax errors and other problems with the code, it really makes a huge difference. Apart from that, another general strategy is to always code in "baby steps": do only the minimal thing to test if the code works, compile and test often. And if you still have troubles, you can always comment out chunks of your code when searching for the offending bits.
Having said that, the errors that I see in your code are:
if (double [][]=new double[3][])
If you want to test the length of the input, you can do if (m.length == 3)
In
if( (m[0].length = n-1) && (m[1].length = n) &&(m[2].length=n-1))
you're not testing for equality, but rather trying to put the values n-1 etc into m[0].length, which is not going to work. What you probably meant was
if( (m[0].length == n-1) && (m[1].length == n) &&(m[2].length==n-1))
In
return true
you're missing a semicolon. The compiler is whiny about things like that and unless you use an IDE or learn to interpret the compiler error messages, it can be really painful to find such errors.
Finally, of course, the answer by vasste provides a much simpler solution to your actual task, so it's worth looking into that :).
Why do you need all that loops? If all arrays cannot be null, than
static boolean isValidTridiagonal(double[][] m) {
return m.length == 3 && m[0].length == m[1].length - 1 && m[2].length == m[0].length;
}
You're missing a few braces at the end but, judging from your indentation, you just forgot to copy them.
You're missing semicolons from the end of the return lines.
The condition within this if statement if (double [][] = new double [3][]) is not a valid expression. You simply want to evaluate the length, which you can do like if (m.length == 3). You did the same thing later on.
The line including (m[0].length = n-1) && (m[1].length = n) && (m[2].length=n-1) is not valid because you are performing assignment (=) in all three cases. An equality check is the double equals operator ==.
You do not return a value in every case. You can fix this by adding return false; after the closing brace of your first if statement, i.e. the last line of the function.
This is enough to get your code to compile. As mentioned in another answer though, your logic is confusing and without actually tracing it through I would speculate that it will not work as you would expect.
If I have understood your requirements correctly, you can rewrite the entire function as:
static boolean isValidTridiagonal ( double [][] m)
{
return m.length == 3 &&
m[0].length + 1 == m[1].length &&
m[2].length + 1 == m[1].length;
}
A proper IDE - Netbeans, Eclipse, etc. - will give you fairly descriptive error messages to show you where you've gone wrong.
This is basically completely stylistic but I wish someone had pointed this out to me earlier. If you ever find yourself writing code in this form:
if( (m[0].length == n-1) && (m[1].length == n) && (m[2].length == n-1))
{
return true;
}
else
{
return false;
}
know that you can save yourself so many lines without losing any readability by instead writing:
return (m[0].length == n-1) && (m[1].length == n) && (m[2].length == n-1);
Is this going to cause unpredictable behavior?
ArrayList<X> x = new ArrayList<>();
//x.add(new X())...
f:
for(int i = 0; i < x.size() -1;)
{
X y = x.get(i);
for(int j = i + 1; j < x.size();)
{
if(a) {
x.remove(j);
continue;
}
if(b) {
x.remove(i);
continue f;
}
j++;
}
i++;
}
I don't think it will be unpredictable, but your style seems wrong to me, so your approach is suspect.
Using a label is a bad idea, and deciding to use it shows that your approach is flawed.
You may want to look at this discussion about deleting on ArrayList, but basically, LinkedList would be fsster:
http://www.velocityreviews.com/forums/t587893-best-way-to-loop-through-arraylist-and-remove-elements-on-the-way.html
But, removing this way will work.
UPDATE:
Oops, just saw a couple of bugs:
if(a) {
x.remove(j);
continue;
}
OK, in this one, you will go back through the loop for j, but you didn't increment j.
if(b) {
x.remove(i);
continue f;
}
This is the same for i.
So, you need a similar change to fix it:
for(int i = 0; i < x.size() -1; i++)
This way, when you hit continue then it will still go to the next element.
It would be better to create an array which contains indexes to remove.
And fill it with indexes in the main for cycle. Than you can do something like this:
Collections.sort(indexesToRemoveArr);
Collections.reverse(indexesToRemoveArr);
for (int indexToRemove : indexesToRemoveArr) {
arr.remove((int) indexToRemove );
}
In that code I remove indexes from end to start. That's why it won't do any problems.
Yes. Compiler will optimize and call x.size() only once. So your terminatin condition becomes incorrect as soon as you remove element.
My friend is making a minesweeper clone and he asked me to help with the part where when you click on a non-mine/non-number 'blank' square it reveals all adjacent blanks. The following is the code I wrote. I can't figure out why it never resolves.
My base case should be when the for loops completely execute and the if statement never returns true.
Is there something I'm missing?
This is in java, by the way. Also, I told him the whole slew of button state changing should be assigned to a method :p
public void revealAdjacentNulls(int r, int c)
{
int ir, ic;
//literal edge cases :P
int rmax = (r == 15) ? r : r + 1;
int cmax = (c == 15) ? c : c + 1;
//check all spaces around button at r,c
for(ir = (r==0) ? 0 : r-1; ir <= rmax; ir++){
for (ic = (c==0) ? 0 : c-1; ic <= cmax; ic++){
//if any are blank and uncovered, reveal them, then check again around the blanks
if (buttons[ir][ic].value == 0 && buttons[ir][ic].isCovered == false)
{
buttons[ir][ic].setEnabled(false); //number uncovered
buttons[ir][ic].setBackground(Color.blue);
buttons[ir][ic].setText(Character.toString(buttons[ir][ic].value));
buttons[ir][ic].isCovered = false;
revealAdjacentNulls(ir, ic);
}
}
}
}
Let's consider the case when r==0 and c==0, and let's assume that buttons[0][0].value == 0 and that buttons[0][0].isCovered == false.
The very first iteration of the loop will cause the function to call itself with the same arguments, 0, 0, and with unchanged state of value and isCovered. This will instantly lead to infinite recursion.
P.S. Check out the Wikipedia article for other flood fill algorithms.
Well for one thing, it will always keep recursing for revealAdjacentNulls(r, c). Your condition is that isCovered must be false - but then you're setting isCovered to false as well. Did you mean to write:
buttons[ir][ic].isCovered = true;
? Or possibly your check should be:
if (buttons[ir][ic].value == 0 && buttons[ir][ic].isCovered)
(It depends on what you mean by "is covered".)
Another case: if r == 15 then the loop will be from 14 (r - 1) to 15 (rmax). If your if statement is true, then there will be infinite recursion. The same applies to c.
This question already has answers here:
Is there a goto statement in Java?
(23 answers)
Closed 9 years ago.
I wrote a program in C++ with some goto statements. Now, I need to write the same program in Java. Is there any goto option in Java? If so, how it can be implemented? Is it same as the C++?
My program is:
#include<stdio.h>
#include<conio.h>
void main()
{
int i,j,k,w,l,q,d;
clrscr();
printf("\nEnter the limit:");
scanf("%d",&k);
for(i = 13; i <= k ; i++)
{
repeat:
j = i%10;
if (j != 0)
{
if(i < 99)
{
for(w = 1; w <= 9; w++)
{
l = 11*w;
if (l == i){
i++;
goto repeat;
}
}
}
if(i > 99)
{
for(q = 1; q<=9 ; q++)
{
d = 111*q;
if (d == i){
i++;
goto repeat;
}
}
}
printf("%d,",i);
}
}
getch();
}
No, Java does not have a goto operator, by design. It's considered harmful.
Your code could be rewritten with continue repeat in place of the goto repeat, if the repeat: label was placed just before the for loop.
E.g.
repeat: for(i=13;i<=k;i++)
and then
continue repeat;
instead of goto repeat
No Java doesn't have goto in active state (but in reserved state). You cannot use it in your program for now (it's a reserved keyword).
And avoid using it in C++ either. You can write your program using smartly placed continue and/or break for both the languages.
Short answer, No.
You can also refer this question
Although goto is a reserved word in Java it is not used in the Java language. But there is a label, an identifier that can be used in conjunction with the break or continue. The purpose of the label it to let an iteration to jump outside of the iteration, it is a bit like goto statement.
Code:
labelA:
// some loop {
continue labelA;
}
I wrote a program in C++ with some goto statements.
No, you didn't. C++ requires that main() returns int, and <stdio.h> is a C library (and conio.h a platform-specific C library). In C++, we spell it <cstdio>, and we don't normally use it anyway (because <iostream> is much more powerful and type-safe). However, your program is valid C.
Now,i need it to write the same program in java.
Good heavens, why? To the extent that I can figure out what your program is actually intended to do, it isn't anything useful at all. If this is for homework, your teacher is doing an incredibly bad job of explaining good coding style, from what I can see.
Is there any goto option in java ?
No, goto is not implemented in Java. They did this because you don't have a reason to use it. No, really. The fact that it's all over the Linux kernel doesn't mean you have a reason. (It doesn't mean they have a real reason, either.)
Your program can be written more simply, for example:
#include<stdio.h>
#include<conio.h>
void main()
{
int i,j,k,w,l,q,d;
clrscr();
printf("\nEnter the limit:");
scanf("%d",&k);
for(i=13;i<=k;i++)
{
j=i%10;
if (j == 0) continue;
if (i<99)
{
for(w=1;w<=9;w++)
{
l=11*w;
if (l==i) continue;
}
}
else
{
for(q=1;q<=9;q++)
{
d=111*q;
if(d==i) continue;
}
}
printf("%d,",i);
}
getch();
}
And the same basic approach will work in Java, too.
Although you really need to work on several other style issues. Please try to use real variable names, and restrict variable scope.
I do condone the use of goto on occasion. This is not one of those occasions. This particular problem can be solved without any kind of goto (break and continue are a goto, just a restricted form).
#include <iostream>
int main()
{
unsigned int lim;
std::cout << "Enter the limit: ";
std::cin >> lim;
std::cout << "\n";
if (lim > 999) {
std::cout << lim << " is too large. Truncating to 999.\n";
lim = 999;
}
// Why start at 13? Oh well.
for (unsigned int ii=13; ii <= lim; ii++) {
if (((ii % 10) != 0) &&
((ii < 100) ? (ii % 11) != 0 : (ii % 111 != 0))) {
std::cout << ii << ",";
}
}
std::cout << "\n";
return 0;
}
There are times where the clearest way to write a chunk of code involves break or continue. There are times where the clearest way to write a chunk of code involves a multi-level break or continue. While Java does provide such a mechanism, neither C nor C++ does.
As I said at the onset, I do condone the use of goto on occasion. The occasions are very, very rare:
To emulate a multi-level break or continue when that truly is the clearest way to write the code.
To deal with errors in a stupid programming environment that mandates single point of entry, single point of return.
To deal with errors in a programming environment that makes try, catch, and throw forbidden keywords.
To implement a finite state machine (but a loop around a switch usually quite nicely in this case).
You can do anything with label that you could do with goto. Labels as an Anti-Pattern This doesn't make it a good idea.
What you are trying to do here doesn't need nested loops which avoids the need to use labels at all.
Scanner in = new Scanner(System.in);
System.out.print("\nEnter the limit:");
int limit = in.nextInt();
for (int i = 12; i <= limit; i++) {
if (i % 10 == 0) continue;
if (i <= 99) {
// two digits the same.
if (i % 10 == i / 10 % 10) continue;
} else if (i <= 999) {
// three digits the same.
if (i % 10 == i / 10 % 10 && i % 10 == i / 100) continue;
} else {
System.err.println("Value " + i + " too large to check");
break;
}
System.out.printf("%d,", i);
}
I was wondering, do you have a neat way of doing this ?
if(orderBean.getFiles().size() > 0 && orderBean.getFiles().size() < 5)
without declaring a variable that is not needed anywhere else ?
int filesCount = orderBean.getFiles().size();
if(filesCount > 0 && filesCount < 5) {
I mean, in for loop we are "declaring conditions" for the actual iteration, one can declare a variable and then specify the conditions. Here one can't do it, and neither can do something like
if(5 > orderBean.getFiles().size() > 0)
Simple utility method:
public static boolean isBetween(int value, int min, int max)
{
return((value > min) && (value < max));
}
Several third-party libraries have classes encapsulating the concept of a range, such as Apache commons-lang's Range (and subclasses).
Using classes such as this you could express your constraint similar to:
if (new IntRange(0, 5).contains(orderBean.getFiles().size())
// (though actually Apache's Range is INclusive, so it'd be new Range(1, 4) - meh
with the added bonus that the range object could be defined as a constant value elsewhere in the class.
However, without pulling in other libraries and using their classes, Java's strong syntax means you can't massage the language itself to provide this feature nicely. And (in my own opinion), pulling in a third party library just for this small amount of syntactic sugar isn't worth it.
If getFiles() returns a java.util.Collection, !getFiles().isEmpty() && size<5 can be OK.
On the other hand, unless you encapsulate the container which provides method such as boolean sizeBetween(int min, int max).
This is one ugly way to do this. I would just use a local variable.
EDIT: If size() > 0 as well.
if (orderBean.getFiles().size() + Integer.MIN_VALUE-1 < Integer.MIN_VALUE + 5-1)
java is not python.
you can't do anything like this
if(0 < i < 5) or if(i in range(0,6))
you mentioned the easiest way :
int i = getFilesSize();
if(0 < i && i < 5){
//operations
}
of
if(0 < i){
if(i < 5){
//operations
}
}
If this is really bothering you, why not write your own method isBetween(orderBean.getFiles().size(),0,5)?
Another option is to use isEmpty as it is a tad clearer:
if(!orderBean.getFiles().isEmpty() && orderBean.getFiles().size() < 5)
Please just write a static method somewhere and write:
if( isSizeBetween(orderBean.getFiles(), 0, 5) ){
// do your stuff
}
Nowadays you can use lodash:
var x = 1;
var y = 5;
var z = 3;
_.inRange(z,x,y);
//results true